是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?
这是我想写的一个简单例子:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)
所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.
在http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx上,VC++团队正式声明他们尚未实现C++ 11核心功能"Expression SFINAE".但是,从http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html复制的以下代码示例将被VC++编译器接受.
例1:
template <int I> struct A {};
char xxx(int);
char xxx(float);
template <class T> A<sizeof(xxx((T)0))> f(T){}
int main()
{
f(1);
}
Run Code Online (Sandbox Code Playgroud)
例2:
struct X {};
struct Y
{
Y(X){}
};
template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1
X f(Y, Y); // #2
X x1, x2;
X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2
Run Code Online (Sandbox Code Playgroud)
我的问题是:什么是"表达SFINAE"?
尝试创建一种方法来识别给定的类是否具有可以调用的给定函数,并返回某种类型.
我在这里做错了什么?有没有更好的方法来确定给定的方法是否可以在给定类的情况下调用?
#include <string>
#include <type_traits>
#define GENERATE_HAS_MEMBER_FUNC(func, rettype) \
template<typename T, class Enable = void> struct has_##func; \
template<typename T, class U> struct has_##func : std::false_type {}; \
template<typename T> \
struct has_##func<T, \
typename std::enable_if<std::is_same< \
typename std::result_of<decltype (&T::func)(T)>::type, \
rettype>::value>::type> : std::true_type{}; \
template<class T> constexpr bool has_##func##_v = has_##func<T>::value;
GENERATE_HAS_MEMBER_FUNC(str, std::string)
GENERATE_HAS_MEMBER_FUNC(str2, std::string)
GENERATE_HAS_MEMBER_FUNC(funca, std::string)
GENERATE_HAS_MEMBER_FUNC(strK, std::string)
GENERATE_HAS_MEMBER_FUNC(fancy, std::string)
GENERATE_HAS_MEMBER_FUNC(really, std::string)
struct A1 {
virtual std::string str() const { return ""; }
std::string strK() const { …Run Code Online (Sandbox Code Playgroud)