c++ - 仅当类型具有 "<<"运算符时才重载?

标签 c++ templates c++11 operator-overloading typetraits

我有一个为许多类型重载的函数。 但我目前的问题是由于此(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() 时对于 std::tuple , 第三个版本被执行而不是第二个。

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

最佳答案

你唯一的问题是你忘记了 #include <tuple> ,这在 LWS 上的错误中显示。 Here's a fixed version编译正确。第二个重载始终比第三个重载匹配得更好,因为根据部分排序规则,它更专业

如果您仍然想知道如何检查是否存在触发 SFINAE 的函数(如果不存在),请查看 this answer of mine关于专门针对该主题的问题。 :) 它甚至有一个与您想要的非常匹配的示例。

关于c++ - 仅当类型具有 "<<"运算符时才重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13056108/

相关文章:

c++ - 在两个函数 C++ 之间发送一个数组

c++ - 是否有指向成员特征或类似内容的指针?

c++ - 这个长长的 "if argA == argB do ..."列表还有其他选择吗?

c++ - 为什么这里不考虑 std::begin/end?

c++ - 递归内存错误

c++ - 是否有 C++11 到 C++03 的转换器?

c++ - boost fusion 问题

c++ - C++ 模板/通用/元编程的最佳设置

c++ - 自动推导返回和参数类型的仿函数

C++11:用于调用类型的默认构造函数的可变参数 lambda 模板