2017-10-20 106 views
0

有人可以解释为什么这个静态断言是错误的吗?如何重新定义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); 
} 

回答

2

的问题是包含在Z类型T不能被推导出来。

作品,如果你明确它,我不知道如何避免明确。

#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, "!"); 
} 

- EDIT 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); 
} 
+0

是的,那是我的备用解决方案,我需要避免。所以没有办法维护我的语法? – prestokeys

+0

@prestokeys - 据我所知,没有。但我不是专家,有人比我更能找到解决方案。也许用C++ 17应该是可能的(但是你标记了C++ 11),但是我也没有用它。 – max66

+0

@prestokeys - 回答有点改进,但​​不完全是你问的 – max66

7

你为什么这样做呢?

你可以做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; 
} 
+0

@布兰登我需要它在编译时进行评估。但你确实给了我一些想法。 – prestokeys

+0

是什么让你认为'sizeof ...'在编译时不会被忽略?就像普通的'sizeof'一样。所以,你可以用更简单的方式创建特征模板。 –

+0

@prestokeys'sizeof ...'是编译时间。你可以在'static_assert'或其他模板中使用它。正确.. + 1。http://en.cppreference.com/w/cpp/language/parameter_pack#The_sizeof..._operator – Brandon

相关问题