std::条件编译时分支评估
编译:
template < class T, class Y, class ...Args >
struct isSame
{
static constexpr bool value = std::conditional<
sizeof...( Args ),
typename std::conditional<
std::is_same< T, Y >::value,
isSame< Y, Args... >, // Error!
std::false_type >::type,
std::is_same< T, Y > >::type::value;
};
int main()
{
qDebug() << isSame< double, int >::value;
return EXIT_SUCCESS;
}
给我这个编译器错误:
error: wrong number of template arguments (1, should be 2 or more)
问题在于 isSame<double, int >
有一个空的 Args
参数包,所以 isSame<Y, Args... >
实际上变成了 isSame<;Y >
与签名不匹配.
The issue is that isSame< double, int >
has an empty Args
parameter pack, so isSame< Y, Args... >
effectively becomes isSame< Y >
which does not match the signature.
但我的问题是:为什么要评估那个分支?sizeof...( Args )
为 false
,因此不应评估内部 std:conditional
.这不是运行时代码,编译器知道 sizeof..( Args )
将永远 是 true
使用给定的模板类型.
But my question is: Why is that branch being evaluated at all? sizeof...( Args )
is false
, so the inner std:conditional
should not be evaluated. This isn't a runtime piece of code, the compiler knows that sizeof..( Args )
will never be true
with the given template types.
如果你很好奇,它应该是 std::is_same
的可变参数版本,而不是它的工作原理......
If you're curious, it's supposed to be a variadic version of std::is_same
, not that it works...
推荐答案
你有一个错误,因为在用作模板参数时类型必须正确.
您可以使用模板专业化来解决您的问题,例如:
You have an error because the type has to be correct when used as template parameter.
You may use template specialization to solve your issue, something like:
#include <type_traits>
template <typename ... Ts> struct are_same;
template <> struct are_same<> : std::true_type {};
template <typename T> struct are_same<T> : std::true_type {};
template <typename T1, typename T2, typename... Ts>
struct are_same<T1, T2, Ts...> :
std::conditional<
std::is_same<T1, T2>::value,
are_same<T2, Ts...>,
std::false_type
>::type
{};
static_assert(are_same<char, char, char>::value, "all type should be identical");
static_assert(!are_same<char, char, int>::value, "all type should not be identical");
相关文章