要回答您对 Kerre 的问题的评论,您可以尝试使用 SFINAE:
#include <type_traits>
#include <string>
template <class T>
struct HasFooImpl_ {
template <typename C>
static std::true_type test(decltype(fooImpl(std::declval<C>()))*);
template <typename C>
static std::false_type test(...);
typedef decltype(test<T>(0)) type;
};
template <typename T>
using HasFooImpl = typename HasFooImpl_<T>::type;
template <typename T>
typename std::enable_if<HasFooImpl<T>::value, std::string>::type
foo(T&& t)
{
return fooImpl(std::forward<T>(t));
}
template <typename T>
typename std::enable_if<!HasFooImpl<T>::value, std::string>::type
foo(T&& t)
{
return "generic!";
}
您必须为fooImpl
您不想被一般处理的任何类型实现一个函数。
实现有点棘手,我只是enable_if<is_same<string, decltype(fooImpl(declval<C>()))>::value
先尝试过,但是对于回退,!is_same<>::value
它给了我编译器错误,因为它也尝试实例化 decltype。
这个实现有一个你可能想或不想使用的警告:如果T
可转换为具有fooImpl
定义的其他类型,则该转换将启动。
你可以在这里看到整个事情:http: //ideone.com/3Tjtvj
更新:
如果您不想允许类型转换,它实际上变得更容易:
#include <type_traits>
#include <string>
template <typename T> void fooImpl(T);
template <typename T>
using HasFooImpl = typename std::is_same<std::string, decltype(fooImpl(std::declval<T>()))>;
template <typename T>
typename std::enable_if<HasFooImpl<T>::value, std::string>::type
foo(T&& t)
{
return fooImpl(std::forward<T>(t));
}
template <typename T>
typename std::enable_if<!HasFooImpl<T>::value, std::string>::type
foo(T&& t)
{
return "generic!";
}
见http://ideone.com/miaoop