【问题标题】:Check if a class has a possibly-overloaded function call operator检查一个类是否有可能重载的函数调用运算符
【发布时间】:2020-10-05 11:50:24
【问题描述】:

我想知道是否可以在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 标准,就欢迎使用最奇怪的模板元编程技巧。

【问题讨论】:

  • &amp;T::operator() 对于 3 个失败案例来说是模棱两可的。
  • 你为什么想知道这个?如果你不知道如何调用一个函数,知道它存在有什么好处?
  • 我感觉像this is a valid duplicate

标签: c++ template-meta-programming sfinae c++20 function-call-operator


【解决方案1】:

&amp;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;

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多