4

我有一个为许多类型重载的函数。但我目前的问题是由于这个(LWS 这里:lws):

#include <iostream>
#include <string>
#include <sstream>
#include <type_traits>

// First version
template<typename T, class = typename std::enable_if<std::is_fundamental<T>::value>::type> 
std::string f(const T& x)
{
    return std::to_string(x);
}

// Second version
template<typename... T> 
std::string f(const std::tuple<T...>& x)
{
    return std::to_string(sizeof...(T)); // It's just an example here
}

// Third version
template<typename T, class = typename std::enable_if<!std::is_fundamental<T>::value>::type, class = void> 
std::string f(const T& x)
{
    std::ostringstream oss;
    oss<<x;
    return oss.str();
}

// Main
int main(int argc, char* argv[])
{
   std::cout<<f(42)<<std::endl;
   std::cout<<f(std::string("Hello World"))<<std::endl;
   std::cout<<f(std::tuple<int, int, int, int, int, int>(4, 8, 15, 16, 23, 42))<<std::endl;
   return 0;
}

我的问题是,当我们调用f()a时std::tuple,会执行第三个版本而不是第二个版本。

如何解决这个问题(一个解决方案是只允许第三个版本用于<<定义的类型,但我不知道该怎么做,如果这是解决问题的最佳方法)?

4

1 回答 1

5

您唯一的问题是您忘记了#include <tuple>,这在 LWS 上的错误中显示。这是一个可以正确编译的固定版本。第二个重载总是比第三个更好的匹配,因为它根据部分排序规则更专业。

如果您仍然想知道如何检查是否存在触发 SFINAE 的函数(如果它不存在),请在专门针对该主题的问题上查看我的这个答案。:) 它甚至有一个非常符合你想要的例子。

于 2012-10-24T19:30:47.957 回答