考虑以下代码:
#include <iostream>
#include <utility>
#include <tuple>
template <class TargetIndices, class SourceIndices>
struct assign;
template <size_t... TargetIs, size_t... SourceIs>
struct assign<std::index_sequence<TargetIs...>, std::index_sequence<SourceIs...>>: assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>... {
template <class TargetTuple, class SourceTuple>
assign(TargetTuple &target, const SourceTuple &source): assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>(target, source)... { }
};
template <size_t FirstTI, size_t FirstSI>
struct assign<std::index_sequence<FirstTI>, std::index_sequence<FirstSI>> {
template <class TargetTuple, class SourceTuple>
assign(TargetTuple &target, const SourceTuple &source) {
std::get<FirstTI>(target) = std::get<FirstSI>(source);
}
};
int main() {
std::tuple<int, int, int> t1 = std::make_tuple(0,0,0), t2 = std::make_tuple(1,2,3);
assign<std::index_sequence<0,2>, std::index_sequence<2,0>>(t1, …
Run Code Online (Sandbox Code Playgroud) 根据cppreference部分核心常量表达式指出19)两个指针之间的减法运算符不是合法的常量表达式,直到c ++ 14.我可以假设以下代码是合法的c ++ 17代码或者这种解释是滥用吗?
int X, Y;
template <long long V>
struct S { };
int main() {
S<&X - &Y> s;
(void)s;
}
Run Code Online (Sandbox Code Playgroud) 根据[此问答],因为c ++ 11逗号运算符是constexpr能力的.根据[此问答], constexpr变量不应该被lambda捕获,但应该可以在其体内使用.
这两条规则都使得以下代码可以在clang中编译:
//Example 1
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
static_cast<void>(Foo<(c, 2)>{});
}
Run Code Online (Sandbox Code Playgroud)
//Example 2
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
auto lambda = []{return c * 2;};
static_cast<void>(Foo<lambda()>{});
}
Run Code Online (Sandbox Code Playgroud)
然而,虽然这两个例子在clang上成功编译(声明constexpr lambda支持是 - 8.0.0),但下面的代码片段没有,我无法想象为什么......任何想法?
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
auto lambda = []{return (c, 2);};
static_cast<void>(Foo<lambda()>{});
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
变量'c'不能在没有指定capture-default的lambda中隐式捕获
考虑一下代码:
#include <string>
#include <sstream>
template <class T>
struct converter_impl {
std::string to_convert;
operator T() {
T result;
std::stringstream ss(to_convert);
ss >> result;
return result;
}
};
struct converter {
std::string to_convert;
template <class T, class CI = converter_impl<T>>
operator T() {
CI ci = CI{std::move(to_convert)};
return ci;
}
};
converter from_string(std::string s) {
return converter{std::move(s)};
}
Run Code Online (Sandbox Code Playgroud)
现在我可以使用from_string
如下函数:
string s = "123";
int x = from_string(s);
cout << x << endl;
Run Code Online (Sandbox Code Playgroud)
我只是好奇是否有办法调用converter
struct 的强制转换操作符显式指定模板参数.语法:
from_string(s).operator int<int, converter_impl<int>>(); …
Run Code Online (Sandbox Code Playgroud) 我能够生成的最小代码来重现问题:
template <int>
struct Tag { };
Tag<0> w;
template <int... Is>
struct Outer {
template <Tag<Is> &...>
struct Inner {
};
};
int main() {
Outer<0>::Inner<w> f;
}
Run Code Online (Sandbox Code Playgroud)
g ++(版本6.1.1 20160511)在编译代码时遇到以下错误:
Run Code Online (Sandbox Code Playgroud)pp.cc: In function ‘int main()’: pp.cc:14:21: internal compiler error: unexpected expression ‘Is’ of kind template_parm_index Outer<0>::Inner<w> f;
并产生长而无聊的堆栈跟踪.版本3.6.0中的clang ++似乎没有编译代码的任何问题.具有类型模板参数的相同代码在两个编译器中编译得很好:
template <class>
struct Tag { };
Tag<int> w;
template <class... Ts>
struct Outer {
template <Tag<Ts> &...>
struct Inner {
};
};
int main() {
Outer<int>::Inner<w> f;
}
Run Code Online (Sandbox Code Playgroud)
那么这是一个g …
考虑一个例子:
#include <type_traits>
template <class T, T>
struct has_duplicates_info { };
template <class T, T...>
struct has_duplicates;
template <class T, T First, T... Others>
struct has_duplicates<T, First, Others...>:
has_duplicates<T, Others...>,
has_duplicates_info<T, First> {
static constexpr bool value =
std::is_base_of<has_duplicates_info<T, First>, has_duplicates<T, Others...>>::value
|| has_duplicates<T, Others...>::value;
};
template <class T, T Last>
struct has_duplicates<T, Last>: has_duplicates_info<T, Last>, std::false_type { };
int a, b;
int main() {
static_assert(!has_duplicates<int, 0, 1, 2>::value, "has_duplicates<int, 0, 1, 2>::value");
static_assert(has_duplicates<int, 1, 2, 2, 3>::value, "!has_duplicates<int, 1, …
Run Code Online (Sandbox Code Playgroud) https://reviews.llvm.org/D15421
clang具有__type_pack_element
允许在可变参数模板中对参数包进行有效索引的功能。是否有等效的GCC?
我对使用不感兴趣tuple_element_t
。我正在寻找一种替代方法,它是编译器原语
我遇到过类似的东西:
using arr_t=std::array<std::array<std::array<int,1000>,1000>,1000>;
std::unique_ptr<arr_t> u_ptr;
Run Code Online (Sandbox Code Playgroud)
显然,使用唯一指针来克服stackoverflow问题.有没有使用以前的代码而不仅仅是使用std::vector
?有真正的用例std::unique_ptr<std::array<T,N>>
吗?
扔烂番茄之前
我知道lambda分解的实际应用目前受到限制,因为无法找到替代失败友好的方法来检查隐藏在分解变量中的lambda捕获数量。这只是一个理论问题,因为我找不到涵盖捕获成员变量访问修饰符的任何标准部分。
例
int main() {
int a;
auto [x] = [a]{};
static_cast<void>(a);
static_cast<void>(x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
标准参考
关于lambda捕获的标准部分很长,因此我可能错过了相关的片段。我注意到的是,重点是对应于捕获的非静态成员必须/未命名。
考虑示例:
template <char>
struct foo { };
int main() {
foo<""[0]?""[1]:'\0'>{};
}
Run Code Online (Sandbox Code Playgroud)
代码在[gcc]和[clang]中编译,但它应该真的吗?我知道表达式""[1]
不需要进行评估,因为它是短路的.但是,如果表达式实际上可以作为核心常量表达式,则标准不是很清楚.相关[expr.const]/2,尤其是部分:
如果e满足核心常量表达式的约束,但e的评估将评估具有本文档的[library]至[thread]中指定的未定义行为的操作,则未指定e是否是核心常量表达式.
引起我的怀疑......