我尝试专用于STL容器的模板(函数或类)。我使用的标准是c ++ 14。
对于模板功能,我尝试如下代码。
template<typename... Args>
using int_t = int;
template<typename T, int_t
<
typename T::value_type, //has defined the element type
typename T::iterator, //has defined the iterator
decltype(std::declval<T>().size()) //has defiend the "size()" function
//other check...
> = 0>
void container_handler()
{
}
我认为,如果“ int_t”中不存在任何类型,则不会实例化模板函数,但是当我按以下方式调用模板函数时,不会发生编译错误。
container_handler<int>();
但是,使用类模板时会得到不同的结果。
template<typename... Args>
using int_t = int;
template<typename T , typename = int>
struct ContainerHandler;
template<typename T>
struct ContainerHandler<T, int_t
<
typename T::value_type, //has defined the element type
typename T::iterator, //has defined the iterator
decltype(std::declval<T>().size()) //has defiend the "size()" function
//other check...
>>
{
};
上面的代码有效,当我使用尚未定义特殊类型或函数的类型实例化类模板时,会发生编译错误。
ContainerHandler<int> handler1; //compile error
ContainerHandler<int, int> handler2; //compile error
ContainerHandler<vector<int>> handler3; //ok
ContainerHandler<vector<int>, int> handler4; //ok
此处的“ int_t”可以在c ++ 17中替换为“ void_t”。 我的问题是,为什么SFINAE规则与功能模板和类模板不同。 对于功能模板,我尝试了另一种方法,并且可以使用。
template<typename... Args>
struct type_container
{
using int_t = int;
};
template<typename T, typename type_container
<
typename T::value_type, //has defined the element type
typename T::iterator, //has defined the iterator
decltype(std::declval<T>().size()) //has defiend the "size()" function
//other check...
>::int_t = 0>
void container_handler()
{
}
container_handler<int>(); //compile error
container_handler<int, 0>(); //compile error
container_handler<vector<int>>(); //ok
container_handler<vector<int>, 0>(); //ok
我不知道使用“ int_t”和“ type_container :: int_t”有什么区别。
答案 0 :(得分:0)
以下两行之所以失败,是因为没有ContainerHandler
的定义会使这些模板参数的模板实例化成功。
ContainerHandler<int> handler1; //compile error
ContainerHandler<int, int> handler2; //compile error
如果要提供模板的定义,例如像这样:
template<typename T , typename = int>
struct ContainerHandler {};
编译将成功。参见demo here。
编辑:
不。我期望在调用模板函数“ container_handler();”时出现编译错误。 (在代码的第一部分)。
int_t
的{{1}}参数具有默认值,这就是为什么它编译container_handler
的原因
没有默认值将使编译失败。
参见demo here。