c++ - 通过模板检查 c++11 中是否存在函数(不是方法)

标签 c++ templates c++11 template-meta-programming sfinae

因此对于 SFINAE 和 c++11,可以根据其中一个模板参数是否可以被替换来实现两个不同的模板函数。

例如

struct Boo{
   void saySomething(){ cout << "Boo!" << endl; }
};

template<class X>
void makeitdosomething(decltype(&X::saySomething), X x){
   x.saySomething();
}

template<class X>
void makeitsaysomething(int whatever, X x){
    cout << "It can't say anything!" << endl;
}


int main(){
   makeitsaysomething(3);
   makeitsaysomething(Boo());
}

或者类似的东西。

我的问题是..如何做同样的事情,但对于非成员函数?

特别是我正在尝试检查是否有这样的东西:

operator<<(std::ostream& os, X& whateverclass);

存在。可以测试吗?

编辑:问题不同于:Is it possible to write a template to check for a function's existence?因为我试图查看函数是否存在,而不是方法

最佳答案

我找到了 void_t通常比其他答案中显示的传统 SFINAE 方法更可取的技巧。

template<class...> using void_t = void; // now in the C++17 working paper!
// GCC <= 4.9 workaround:
// template<class...> struct voider { using type = void; };
// template<class... T> using void_t = typename voider<T...>::type;

template<class, class = void>
struct is_ostreamable : std::false_type {};

template<class T>
struct is_ostreamable<T, void_t<decltype(std::declval<std::ostream&>() <<
                                         std::declval<T>())>> : std::true_type {};

当且仅当表达式的格式正确时,才会选择偏特化。

Demo . 请注意 &std::declval<std::ostream&>()很重要,因为否则 std::declval<std::ostream>()是一个右值,你会得到 ostream的 catchall 右值流插入运算符,并报告一切都是可流式的。

以上代码检查 operator<<可以接受 T右值。如果你想检查一个接受左值的 T , 然后使用 std::declval<T&>() .

关于c++ - 通过模板检查 c++11 中是否存在函数(不是方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29319000/

相关文章:

c++ - C++ 中的 WinRT API WIndows::System::Launcher::LaunchFileAsync() 用法

c++ - 如何重载/专门化模板类函数来处理算术类型和容器类

c++模板成员函数,根据模板参数更改参数

c++ - 在 C++ 模板参数中不使用 constexpr

c++ - 为什么需要复制扣除候选作为单独的扣除指南?

c++ - 使用 Libcurl 库进行文件下载

c++ - 编写一个从类型列表返回类型的元函数,该类型列表具有 C++11 中给定类型的 typedef

c++ - 执行中断信号时服务器停止操作的最佳方法是什么?

c++ - 将成员函数传递给需要回调的 C 接口(interface)

templates - FOSUserBundle:如何最好地将登录和注册表单集成到一个模板中?