如何实现is_polymmorphic_functor
How to implement is_polymorphic_functor?
我正在尝试实现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 Tita的解决方案的几个测试用例,该解决方案在两个测试用例中都失败了。
我试过这个:
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);
};
其试图利用CCD_ 3的以下实现:
//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
按预期工作?
这对我有效:
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;
};
给定非多态函子没有重载的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);
};
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
上也为真,并且只有在(任意计算返回1)时才在double
上为真。
因此,毫不妥协的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,则每个类型都会发生第一个过载。
相关文章:
- Why is UINT32_MAX + 1 = 0?
- C++错误:"error: int aaa::bbb is protected within this context"
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- Is !NaN not a NaN?
- Directx 11 - CompileFromFile() is not compiling
- Centos7 g++ "to_string is not in a member of std"
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- Where is std::hardware_destructive_interference_size?
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- What is unordered_set in C++
- 你如何理解"std: :forward is just syntactic sugar"?这是真的吗?
- C++ "error: use of overloaded operator '*' is ambiguous"似乎只有一场比赛
- C++ is calculating wrong
- Is it good to use SDL_PIXELFORMAT_UNKNOWN?
- reference_wrapper导致"incomplete type is not allowed"
- 为什么即使在定义之后仍存在"Identifier is undefined error "?
- 结构中的错误"Incomplete type is not allowed"
- Crash in boost::archive::text_iarchive in_archive {is} boost
- 在反转字符串'my.name.is'时,我得到的输出为"is@.name.my"。我不明白'@'是从哪里来的