【发布时间】:2018-03-08 06:01:52
【问题描述】:
问题描述:
C++17 引入了std::invocable<F, Args...>,它可以很好地检测类型...是否可以使用给定的参数调用。但是,是否有办法对函子的任何参数执行此操作(因为标准库的现有特征的组合已经允许检测函数、函数指针、函数引用、成员函数......)?
换句话说,如何实现以下类型特征?
template <class F>
struct is_functor {
static constexpr bool value = /*using F::operator() in derived class works*/;
};
使用示例:
#include <iostream>
#include <type_traits>
struct class0 {
void f();
void g();
};
struct class1 {
void f();
void g();
void operator()(int);
};
struct class2 {
void operator()(int);
void operator()(double);
void operator()(double, double) const noexcept;
};
struct class3 {
template <class... Args> constexpr int operator()(Args&&...);
template <class... Args> constexpr int operator()(Args&&...) const;
};
union union0 {
unsigned int x;
unsigned long long int y;
template <class... Args> constexpr int operator()(Args&&...);
template <class... Args> constexpr int operator()(Args&&...) const;
};
struct final_class final {
template <class... Args> constexpr int operator()(Args&&...);
template <class... Args> constexpr int operator()(Args&&...) const;
};
int main(int argc, char* argv[]) {
std::cout << is_functor<int>::value;
std::cout << is_functor<class0>::value;
std::cout << is_functor<class1>::value;
std::cout << is_functor<class2>::value;
std::cout << is_functor<class3>::value;
std::cout << is_functor<union0>::value;
std::cout << is_functor<final_class>::value << std::endl;
return 0;
}
应该输出001111X。在理想的世界中,X 应该是 1,但我认为在 C++17 中是不可行的(参见奖励部分)。
编辑:
This post 似乎提出了解决问题的策略。但是,在C++17 中是否有更好/更优雅的方式来做到这一点?
奖励:
作为奖励,有没有办法让它在 final 类型上工作(但这完全是可选的,可能不可行)?
【问题讨论】:
-
那么你想看看一个类型是否一般可调用,而不需要指定任何参数?
-
是的,因为标准库已经允许为非仿函数轻松地做到这一点。
-
为什么需要这个?某些东西是否通常可调用不是有用的信息。
-
@Vincent 您可以使用转换为任何类型的类型,如 example 中的任何类型,但如果模板 operator() 使用 SFINAE 或概念约束其模板参数,它将失败。
标签: c++ c++17 template-meta-programming functor sfinae