通常,当我编写专门化的模板时,我首先使用前向声明,并声明这些案例属于专门化。在您的情况下,我了解您正在尝试编写一个没有空大小写的可变参数模板(也就是说,一个可变参数模板至少可以有一种类型)。
您的代码让我感到惊讶,因为我认为您是正确的,您的 trait 的完整可变参数特化与空洞情况相匹配...首先我尝试使用您的 trait 类的前向声明,并仅定义完整可变参数特化(因此,如果特征的参数不是Wrapper
编译失败的实例)。这正是发生的事情,再次让我失望:
#include <iostream>
#include <utility>
template<typename F , typename... T>
struct Wrapper {};
template<typename T>
struct is_wrapper;
//template<typename T>
//struct is_wrapper : std::false_type {};
template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};
//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};
using my_wrapper_type = Wrapper<int,double>;
int main()
{
std::cout << std::boolalpha << is_wrapper<my_wrapper_type>::value << std::endl;
}//"Invalid use of incomplete type" ^^^^^^^^^^^^^^^^^^^^^^^^^^^
最后我尝试了Wrapper
类中的前向声明方法。令人惊讶的是,它有效:
#include <iostream>
#include <utility>
template<typename... T>
struct Wrapper;
template<typename F, typename... T>
struct Wrapper<F,T...>{ };
template<typename T>
struct is_wrapper : std::false_type {};
template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};
//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};
using my_wrapper_type = Wrapper<int,double>;
int main()
{
std::cout << std::boolalpha << is_wrapper<my_wrapper_type>::value << std::endl;
}
这打印:
真的
这是在 ideone 运行的代码。
真诚地,我不明白为什么您的代码失败而我的代码有效。它是一个编译器错误,还是我们缺少什么?我不知道。