【发布时间】:2018-02-07 22:21:48
【问题描述】:
我对 SFINAE 有疑问。我错过了一些重要的东西,阅读其他问题也无济于事:(
代码如下:
#include <string>
#include <type_traits>
#include <iostream>
// version with template class
template<typename T, typename = std::enable_if_t<
std::is_integral<std::remove_reference_t<T>>::value
|| std::is_floating_point<std::remove_reference_t<T>>::value
>
>
struct to_my_string
{
std::string operator()(T numerical)
{
return std::to_string(numerical);
}
};
template<typename T, typename = std::enable_if_t< std::is_same<T, std::string>::value > >
struct to_my_string
{
std::string operator()(T str)
{
return "'" + str + "'";
}
};
// version with template method
template<typename T, typename = std::enable_if_t<
std::is_integral<std::remove_reference_t<T>>::value
|| std::is_floating_point<std::remove_reference_t<T>>::value
>
>
std::string to_string_method(T numerical)
{
return std::to_string(numerical);
}
template<typename T, typename = std::enable_if_t< std::is_same<T, std::string>::value > >
std::string to_string_method(T str)
{
return "'" + str + "'";
}
int main()
{
std::cout << "start" << std::endl;
return 0;
}
我已经粘贴了两种方法 - 一个类和一个方法方法。两者都产生类似的错误: 以下是 g++ 的错误(clang 给出了类似的错误):
g++ --std=c++14 sfinae_failure.cpp
sfinae_failure.cpp:21:12: error: redefinition of default argument for ‘class<template-parameter-1-2>’
struct to_my_string
^
sfinae_failure.cpp:7:26: note: original definition appeared here
template<typename T, typename = std::enable_if_t<
^
sfinae_failure.cpp:43:17: error: redefinition of ‘template<class T, class> std::__cxx11::string to_string_method(T)’
std::string to_string_method(T str)
^
sfinae_failure.cpp:37:17: note: ‘template<class T, class> std::__cxx11::string to_string_method(T)’ previously declared here
std::string to_string_method(T numerical)
^
我的主要问题是为什么它不起作用,即使我在 enable_if_t 中使用 T 类型。我错过了什么?
附加的问题是 - 我认为模板类/方法在使用时会被实例化。正如您在 main 方法中看到的那样 - 它们不是。
即使这个话题被多次触及,我也非常感谢这里的帮助......
【问题讨论】:
-
一个常见的错误是声明两个仅在默认模板参数上有所不同的函数模板。这是非法的,因为默认模板参数不是函数模板签名的一部分,并且用相同的签名声明两个不同的函数模板是非法的en.cppreference.com/w/cpp/types/enable_if
-
对于基于结构的版本,您需要有一个基础模板(在这种情况下可能是一个空结构),然后为您的情况专门。
-
抛开SFINAE,您没有正确实现模板专业化。首先了解如何进行模板专业化,然后尝试将 SFINAE 添加到您的专业化中。
-
@DrewDormann,我想我昨天在类模板专业化方面有点停电:|