C++ 模板:仅当类具有该方法时才执行该方法

C++ 模板:仅当类具有该方法时才执行该方法,c++,templates,template-function,C++,Templates,Template Function,我想写一个函数,它执行某个模板类的方法,但是如果该类没有它,它也应该可以很好地编译。在这种情况下,它不应该调用函数 struct A { void func() {} }; struct B { }; template <typename T> void anotherFunc(T t) { //do t.func() here if T implements func, just do nothing if it doesn't. } 结构A { void fun

我想写一个函数,它执行某个模板类的方法,但是如果该类没有它,它也应该可以很好地编译。在这种情况下,它不应该调用函数

struct A
{
   void func() {}
};

struct B
{
};

template <typename T>
void anotherFunc(T t)
{
   //do t.func() here if T implements func, just do nothing if it doesn't.
}
结构A { void func(){} }; 结构B { }; 模板 无效另一个函数(T) { //这里的do t.func()如果t实现了func,则不执行任何操作。 } 这有可能吗?

//type\u sink接受一个类型并丢弃它。type_sink_t是一种使用别名的C++1y样式
// type_sink takes a type, and discards it.  type_sink_t is a C++1y style using alias for it
template<typename T> struct type_sink { typedef void type; };
template<typename T> using type_sink_t = typename type_sink<T>::type;

// has_func is a traits class that inherits from `true_type` iff the expression t.func()
// is a valid one.  `std::true_type` has `::value=true`, and is a good canonical way to
// represent a compile-time `bool`ean value.
template<typename T,typename=void> struct has_func : std::false_type {};
template<typename T> struct has_func<
  T,
  type_sink_t< decltype( std::declval<T&>().func() ) >
> : std::true_type {};

// helpers for tag dispatching.
namespace helper_ns {
  template<typename T> void anotherFunc( T&& t, std::false_type /* has_func */ ) {}
  template<typename T> void anotherFunc( T&& t, std::true_type /* has_func */ ) {
    std::forward<T>(t).func();
  }
}
// take the type T, determine if it has a .func() method.  Then tag dispatch
// to the correct implementation:
template<typename T> void anotherFunc(T t) {
  helper_ns::anotherFunc( std::forward<T>(t), has_func<T>() );
}
模板结构类型_sink{typedef void type;}; 使用type\u sink\u t=typename type\u sink::type的模板; //has_func是一个traits类,它从表达式t.func()的'true_type'继承而来 //是有效的`std::true_type`has`::value=true`,是一种很好的规范化方法 //表示编译时的'bool'值。 模板结构有_func:std::false_type{}; 模板结构具有_func< T type_sink_t >:std::true_type{}; //标签分派的助手。 名称空间帮助器{ 模板void anotherFunc(T&&T,std::false_type/*具有_func*/){ 模板void anotherFunc(T&T,std::true\u type/*具有\u func*/){ std::forward(t.func(); } } //以类型T为例,确定它是否有.func()方法。然后标签发送 //要正确实施: 模板无效另一个函数(T){ helper_ns::anotherFunc(std::forward(t),has_func()); }

是一个C++11解决方案,它对traits类进行标记分派,确定
t.func()
是否为有效表达式。

是的,这是可能的。谷歌搜索SFINAE和C++11(如果您正在使用它)。另请参见@0x499602D2:为什么什么?@Yakk:为什么您需要
type_sink
?删除它并只保留
decltype(std::declval().func())
似乎很有效。@JanHudec这是一个很好的解决方案,但我希望有一些更惯用的方法,比如
模板自动帮助器(T&&T)->decltype(std::declval().f(),void(){T.f();}void帮助器(…){}
@0x499602D2:如何回答这个问题?这看起来简单多了,而且似乎已经足够了。@Yakk:我用g++4.9.0、clang++3.4和g++4.8.1试过了。代码是。