为什么没有选择模板专业化?
Why is the template specialization not chosen?
我写了以下代码:
#include <iostream>
#include <string>
#include <type_traits>
template<typename, typename = void>
struct is_incrementable : std::false_type {};
template<typename T>
struct is_incrementable<T, decltype( ++std::declval<T&>() )> : std::true_type {};
int main()
{
std::cout << is_incrementable<std::string>::value << std::endl;
std::cout << is_incrementable<int>::value << std::endl;
}
当我运行它时,我得到0 0
.但我期待0 1
.
有什么想法吗?
对于std::string
,选择主要模板并考虑专业化。但是decltype(++std::declval<T&>())
格式不正确,因此不考虑它并使用主模板(非专用模板(,从而导致0
。
如果你使用int
,它会变得有点复杂。与往常一样,编译器选择主模板,然后考虑专用化(这是因为专用化始终被认为是更好的匹配(。专用化对于int
<int, int&>
,但它与非专用模板<int, void>
不匹配(void
是默认模板参数(,因此会忽略专用化,因为它不匹配。
因此,默认模板参数的类型必须匹配,否则不考虑专用化,因为仅当每个模板参数都与专用化匹配时才采用专用化。
只需在末尾附加一个void()
即可使专用化与第二个模板参数匹配,因为左侧表达式将被丢弃,void()
的类型为 void
,这与主模板的第二个模板参数匹配。
template<typename T>
struct is_incrementable<T, decltype( ++std::declval<T&>(), void() )> : std::true_type {};
在 C++17 中,您将为此使用 std::void_t
。
相关文章:
- 函数模板部分专业化-有什么解决方法吗
- 有选择地禁用第三方库的C++核心准则检查器
- 有选择地禁用库中的死代码消除
- C++,有选择地应用模板模式来发挥作用
- 使用 SFINAE 有选择地实例化模板的成员函数
- 有选择地隐藏类成员的成员
- 有选择地启用一个并行区域内的OpenMP进行循环
- 有选择地对向量 c++ 进行排序
- 有选择地替换 C++ 中 std::string 中的 (") 双引号
- 我可以在代码库中有选择地禁用RTTI以减少二进制尺寸
- 如何有选择地从缓冲区读取数据
- 有选择地覆盖模板化类的函数
- 有选择地编译框架C++的方法
- 为什么内联模板专业化有帮助?我应该这样做吗
- 运算符 = 重载C++有选择地工作
- 有选择地内联函数(用于调试目的)
- 我可以使用 SFINAE 有选择地定义模板类中的成员变量吗?
- 在空格上有选择地分割字符串
- 如何*有选择地*修改由随机数生成的多维数组?
- 在Java中使用SWIG,我如何有选择地SWIG一个巨大的C/ c++头文件的某些部分