我正在尝试实现is_polymorphic_functor元函数,以获得以下结果:
//non-polymorphic functor
template<typename T> struct X { void operator()(T); };
//polymorphic functor
struct Y { template<typename T> void operator()(T); };
std::cout << is_polymorphic_functor<X<int>>::value << std::endl; //false
std::cout << is_polymorphic_functor<Y>::value << std::endl; //true那只是个例子。理想情况下,它应该适用于任意数量的参数,即operator()(T...)。以下是更多的测试用例,我曾经测试@Andrei的解决方案,它在两个测试用例中失败。
我试过这个:
template<typename F>
struct is_polymorphic_functor
{
private:
typedef struct { char x[1]; } yes;
typedef struct { char x[10]; } no;
static yes check(...);
template<typename T >
static no check(T*, char (*) [sizeof(functor_traits<T>)] = 0 );
public:
static const bool value = sizeof(check(static_cast<F*>(0))) == sizeof(yes);
};试图使用以下functor_traits实现的
//functor traits
template <typename T>
struct functor_traits : functor_traits<decltype(&T::operator())>{};
template <typename C, typename R, typename... A>
struct functor_traits<R(C::*)(A...) const> : functor_traits<R(C::*)(A...)>{};
template <typename C, typename R, typename... A>
struct functor_traits<R(C::*)(A...)>
{
static const size_t arity = sizeof...(A) };
typedef R result_type;
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<A...>>::type type;
};
};它为多态函子提供了以下错误:
error: decltype cannot resolve address of overloaded function如何解决此问题并使is_polymorphic_functor按预期工作?
发布于 2013-02-16 17:07:31
这对我来说很管用:
template<typename T>
struct is_polymorphic_functor
{
private:
//test if type U has operator()(V)
template<typename U, typename V>
static auto ftest(U *u, V* v) -> decltype((*u)(*v), char(0));
static std::array<char, 2> ftest(...);
struct private_type { };
public:
static const bool value = sizeof(ftest((T*)nullptr, (private_type*)nullptr)) == 1;
};发布于 2013-02-16 17:51:06
假定非多态函子没有重载的operator()
template<typename T>
class is_polymorphic_functor {
template <typename F, typename = decltype(&F::operator())>
static constexpr bool get(int) { return false; }
template <typename>
static constexpr bool get(...) { return true; }
public:
static constexpr bool value = get<T>(0);
};发布于 2013-02-16 18:23:45
template<template<typename>class arbitrary>
struct pathological {
template<typename T>
typename std::enable_if< arbitrary<T>::value >::type operator(T) const {}
};上面的函子是非多态的当且仅当有一个T使得arbitrary<T>::value是真的.
不难创建一个template<T>函子,它在int和可能的double上是真的,只有在double上才是正确的(任意计算返回1)。
所以一个不妥协的is_polymorphic超出了这个宇宙的范围。
如果您不喜欢上面的内容(因为它显然需要的不仅仅是int,其他类型只是找不到重载),我们可以这样做:
template<template<typename>class arbitrary>
struct pathological2 {
void operator()(int) const {}
template<typename T>
typename std::enable_if< arbitrary<T>::value >::type operator(T) const {}
};如果第二个“重载”被测试,如果没有这样的T,那么每个类型都会发生第一个过载。
https://stackoverflow.com/questions/14912703
复制相似问题