检查类是否具有可能重载的函数调用运算符



我想知道是否可以在C++20中实现一个特征来检查类型T是否具有可能过载/可能模板化的函数调用运算符:operator()

// Declaration
template <class T>
struct has_function_call_operator;
// Definition
???  
// Variable template
template <class T>
inline constexpr bool has_function_call_operator_v 
= has_function_call_operator<T>::value;

以便如下代码将导致正确的结果:

#include <iostream>
#include <type_traits>
struct no_function_call_operator {
};
struct one_function_call_operator {
constexpr void operator()(int) noexcept;
};
struct overloaded_function_call_operator {
constexpr void operator()(int) noexcept;
constexpr void operator()(double) noexcept;
constexpr void operator()(int, double) noexcept;
};
struct templated_function_call_operator {
template <class... Args>
constexpr void operator()(Args&&...) noexcept;
};
struct mixed_function_call_operator
: overloaded_function_call_operator
, templated_function_call_operator {
};
template <class T>
struct has_function_call_operator: std::false_type {};
template <class T>
requires std::is_member_function_pointer_v<decltype(&T::operator())>
struct has_function_call_operator<T>: std::true_type {};
template <class T>
inline constexpr bool has_function_call_operator_v 
= has_function_call_operator<T>::value;
int main(int argc, char* argv[]) {
std::cout << has_function_call_operator_v<no_function_call_operator>;
std::cout << has_function_call_operator_v<one_function_call_operator>;
std::cout << has_function_call_operator_v<overloaded_function_call_operator>;
std::cout << has_function_call_operator_v<templated_function_call_operator>;
std::cout << has_function_call_operator_v<mixed_function_call_operator>;
std::cout << std::endl;
}

目前它打印01000而不是01111。如果它在最广泛的意义上不可行,则可以假设T是可继承的,如果有帮助的话。最奇怪的模板元编程技巧是受欢迎的,只要它们完全符合C++20标准。

&T::operator()

对于3 个失败的情况是模棱两可的。

所以你发现的特征是有一个明确的operator()

由于您允许 T 不final,我们可能会将您的特征应用于具有现有继承operator()和类的(假(类来测试:

template <class T>
struct has_one_function_call_operator: std::false_type {};
template <class T>
requires std::is_member_function_pointer_v<decltype(&T::operator())>
struct has_one_function_call_operator<T>: std::true_type {};
struct WithOp
{
void operator()() const;  
};
template <typename T>
struct Mixin : T, WithOp {};
// if T has no `operator()`, Mixin<T> has unambiguous `operator()` coming from `WithOp`
// else Mixin<T> has ambiguous `operator()`
template <class T>
using has_function_call_operator =
std::bool_constant<!has_one_function_call_operator<Mixin<T>>::value>;
template <class T>
inline constexpr bool has_function_call_operator_v 
= has_function_call_operator<T>::value;

演示

相关内容

  • 没有找到相关文章

最新更新