当函数不存在时,SFINAE回退

Ale*_*uch 4 c++ templates sfinae enable-if

我目前正在尝试实现一个toString函数,该函数调用.toString()std::to_string()取决于推导类型可用的函数

到目前为止,我有这个工作片段:

#include <iostream>
#include <string>

template <class T>
auto toString(const T& obj)
        -> decltype(obj.toString(), std::string())
{
  return obj.toString();
}

template <class T>
auto toString(const T& obj)
        -> decltype(std::to_string(obj), std::string())
{
  return std::to_string(obj);
}

template <class T>
auto toString(const T& obj)
        -> decltype(std::string(obj))
{
  return std::string(obj);
}

class Foo{
public:
  std::string toString() const {
    return "Hello";
  }
};

int main()
{
  Foo bar;
  std::cout << toString(bar);
  std::cout << toString(5);
  std::cout << toString("Hello const char*");
}
Run Code Online (Sandbox Code Playgroud)

现在我想插入一个static_assert当上面的那些没有重载是可行的,因为旧的GCC版本的默认GCC错误消息不是很有用.

我如何检查是否.toString()std::to_string()不可能T

到目前为止,我没有发现任何的方法来检查,如果事情是存在,只有周围的其他方法.我希望有人知道如何解决这个问题并感谢你的时间.

Rak*_*111 8

你需要引入一个比你现在拥有的更糟糕的重载,并删除它.您不需要检查这两个字符串函数是否都存在.

一种流行的方法是使用C风格的可变参数:

std::string toString(...) = delete;
Run Code Online (Sandbox Code Playgroud)


m.s*_*.s. 5

您还可以使用static_assert自定义错误消息:

class Dummy
{
public:
    std::string toString() const;    
private:
    Dummy() = default;
};

template <typename... Ts>
auto toString(Ts...)
{
    static_assert(std::is_same<std::tuple<Ts...>, std::tuple<Dummy>>::value, "neither std::to_str nor member toString() exists");
    return "";
}
Run Code Online (Sandbox Code Playgroud)

实例

  • @WF更新了示例以解决此问题 (3认同)