【问题标题】:Question about SFINAE of class template and function template关于类模板和函数模板的SFINAE问题
【发布时间】:2019-07-19 20:43:13
【问题描述】:

我尝试为 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”有什么区别。

【问题讨论】:

  • 我不明白你在问什么。看起来一切都在按照您的意愿进行 - 有什么问题?
  • 没有。我希望在调用模板函数“container_handler();”时会出现编译错误(在代码的第一部分)。

标签: c++ c++11 templates c++14


【解决方案1】:

以下两行失败的原因是没有ContainerHandler 的定义可以使带有这些模板参数的模板实例化成功。

ContainerHandler<int> handler1; //compile error
ContainerHandler<int, int> handler2; //compile error

如果您要为模板提供定义,例如像这样:

template<typename T , typename = int>
struct ContainerHandler {};

编译会成功。见demo here

编辑:

没有。我希望调用模板函数“container_handler();”时会出现编译错误(在代码的第一部分)。

container_handlerint_t 参数有一个默认值,这就是它编译 container_handler&lt;int&gt;(); 的原因 没有默认值会导致编译失败。
demo here

【讨论】:

  • 感谢您的演示。这个我知道,编译错误在我的预料之内。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
相关资源
最近更新 更多