有人可以解释为什么这个静态断言是错误的吗?如何重新定义is_empty
以便它按照我想要的方式工作(不改变语法)?默认情况下我想要评估为false的包类型(例如is_empty<int>::value
应为false)。
#include <type_traits>
template <typename Pack> struct is_empty : std::false_type {};
template <typename T, template <T...> class Z, T... Is>
struct is_empty<Z<Is...>> : std::true_type {};
template <typename T, template <T...> class Z, T First, T... Rest>
struct is_empty<Z<First, Rest...>> : std::false_type {};
template <int...> struct Z;
int main() {
static_assert(is_empty<Z<>>::value);
}
答案 0 :(得分:10)
为什么这样做?
你可以sizeof...(args)
来确定参数包的长度..如果它是0,那么它是空的:
#include <iostream>
template<typename... Args>
void func(Args... args)
{
std::cout<<(sizeof...(args));
}
int main() {
func(1, 2, 3);
func();
func(1);
func(1, 2);
func(1, 2, 3, 4);
return 0;
}
答案 1 :(得分:2)
问题是T
中包含的Z
类型无法推断出来。
如果您明确表示并且我不知道如何避免明确的话,则可以使用。
#include <type_traits>
template <typename...>
struct is_empty : std::false_type
{ };
template <typename T, template <T...> class Z, T... Is>
struct is_empty<T, Z<Is...>> : std::true_type
{ };
template <typename T, template <T...> class Z, T First, T... Rest>
struct is_empty<T, Z<First, Rest...>> : std::false_type
{ };
template <int...> struct Z;
int main() {
static_assert(is_empty<int, Z<>>::value, "!");
}
- 编辑 -
如果您的Z
需要第一个参数类型(以std::integer_sequence
的方式),则有效;通过这种方式,演绎工作
#include <type_traits>
template <typename>
struct is_empty : std::false_type
{ };
template <typename T, template <typename U, U...> class Z, T... Is>
struct is_empty<Z<T, Is...>>
: std::integral_constant<bool, sizeof...(Is) == 0U>
{ };
template <typename T, T ...>
struct X
{ };
template <int ... Is>
using Y = X<int>;
int main ()
{
static_assert(is_empty<X<int>>::value, "!");
static_assert(is_empty<Y<>>::value, "!");
}
- 编辑2 -
在C ++中,17适用于auto
#include <type_traits>
template <typename Pack>
struct is_empty : std::false_type
{ };
template <template <auto...> class Z, auto... Is>
struct is_empty<Z<Is...>> : std::bool_constant<sizeof...(Is) == 0U>
{ };
template <int...>
struct X;
int main()
{
static_assert( true == is_empty<X<>>::value );
static_assert( false == is_empty<X<1>>::value );
static_assert( false == is_empty<int>::value );
}