强制非推导上下文 - type_identity 等
Force non-deduced context - type_identity etc
我正在尝试制作一个模板,该模板推导与一个模板参数关联的类型,同时在非推导上下文中处理其他类型。下面提供了一个最小的例子。我可以使用两个演绎上下文来完成我正在寻找的事情,但是可以在一个演绎上下文中完成吗?我想我会尝试使用类似 type_identity
的东西,但我没有任何运气。
实例:https://onlinegdb.com/By0iDOM-P
template<size_t... Idx, size_t s>
void foo(index_sequence<Idx..., s>) {
cout << s << endl;
}
template<typename T>
struct TypeIdentity {
using Type = T;
};
template<typename T>
using Identity = typename TypeIdentity<T>::Type;
template<typename... Idx, size_t s>
void bar(index_sequence<Identity<Idx>{}..., s>) {
cout << s << endl;
}
template<size_t s>
void baz(index_sequence<0, s>) {
cout << s << endl;
}
template<size_t... Idx>
struct Qux {
template<size_t s>
static void qux(index_sequence<Idx..., s>) {
cout << s << endl;
}
};
int main()
{
foo<0>(make_index_sequence<2>{}); // couldn't deduce template parameter ‘s’
bar<integral_constant<size_t, 0>>(make_index_sequence<2>{}); // couldn't deduce template parameter ‘s’
baz(make_index_sequence<2>{});
Qux<0>::template qux(make_index_sequence<2>{});
return 0;
}
没有。问题是 Idx...
pack 太贪心了,没有给 s
留下任何东西。您可以使用 s, Idx...
获取第一个值,但不能使用 Idx..., s
获取最后一个值。 TypeIdentity
不会帮助你做到这一点,你需要一些其他技巧。
例如解包成数组(C++14):
template<std::size_t first, std::size_t... rest>
void foo(std::index_sequence<first, rest...>) {
const std::size_t indices[]{first, rest...};
const std::size_t last = indices[sizeof...(rest)];
std::cout << last << std::endl;
}
或使用 fold expression with a comma operator (C++17):
template<std::size_t first, std::size_t... rest>
void foo(index_sequence<first, rest...>) {
const std::size_t last = (first, ..., rest);
std::cout << last << std::endl;
}
我隔离了 first
以确保整个包 first, rest...
永远不会空着。
我正在尝试制作一个模板,该模板推导与一个模板参数关联的类型,同时在非推导上下文中处理其他类型。下面提供了一个最小的例子。我可以使用两个演绎上下文来完成我正在寻找的事情,但是可以在一个演绎上下文中完成吗?我想我会尝试使用类似 type_identity
的东西,但我没有任何运气。
实例:https://onlinegdb.com/By0iDOM-P
template<size_t... Idx, size_t s>
void foo(index_sequence<Idx..., s>) {
cout << s << endl;
}
template<typename T>
struct TypeIdentity {
using Type = T;
};
template<typename T>
using Identity = typename TypeIdentity<T>::Type;
template<typename... Idx, size_t s>
void bar(index_sequence<Identity<Idx>{}..., s>) {
cout << s << endl;
}
template<size_t s>
void baz(index_sequence<0, s>) {
cout << s << endl;
}
template<size_t... Idx>
struct Qux {
template<size_t s>
static void qux(index_sequence<Idx..., s>) {
cout << s << endl;
}
};
int main()
{
foo<0>(make_index_sequence<2>{}); // couldn't deduce template parameter ‘s’
bar<integral_constant<size_t, 0>>(make_index_sequence<2>{}); // couldn't deduce template parameter ‘s’
baz(make_index_sequence<2>{});
Qux<0>::template qux(make_index_sequence<2>{});
return 0;
}
没有。问题是 Idx...
pack 太贪心了,没有给 s
留下任何东西。您可以使用 s, Idx...
获取第一个值,但不能使用 Idx..., s
获取最后一个值。 TypeIdentity
不会帮助你做到这一点,你需要一些其他技巧。
例如解包成数组(C++14):
template<std::size_t first, std::size_t... rest>
void foo(std::index_sequence<first, rest...>) {
const std::size_t indices[]{first, rest...};
const std::size_t last = indices[sizeof...(rest)];
std::cout << last << std::endl;
}
或使用 fold expression with a comma operator (C++17):
template<std::size_t first, std::size_t... rest>
void foo(index_sequence<first, rest...>) {
const std::size_t last = (first, ..., rest);
std::cout << last << std::endl;
}
我隔离了 first
以确保整个包 first, rest...
永远不会空着。