确定将类型作为引用传递时将调用哪个重载

Determine which overload will be called when passing type as reference

本文关键字:调用 重载 引用 类型      更新时间:2023-10-16

我有自由函数foo这些函数对于用户定义的类型X重载如下(C是调用foo的库类型):

template <typename C>
void foo(C&, const X&) {...}

我能够在编译时确定特定类型是否存在重载X

template <typename... Args>
auto foo_exists(int) -> decltype(std::bind<void(*)(Args...)>(&foo, std::declval<Args>()...), std::true_type());
template <typename... Args>
auto foo_exists(char) -> std::false_type;
struct Caller
{
    template <typename T>
    void call(const T& x)
    {
        static_assert(decltype(foo_exists<decltype(*this), const T&>(0))::value, "");
    }
};

现在假设以下类层次结构具有BaseDerivedfoo重载:

struct Base{};
struct Derived : Base {};
struct Leaf : Derived{};
template <typename C>
void foo(C&, const Base&) { std::cout << "Base" << std::endl; }
template <typename C>
void foo(C&, const Derived&) { std::cout << "Derived" << std::endl; }

如何确定在调用foo(..., Leaf())时,将调用const Derived&重载?

一般而言:

我想测试foo的确切类型,以找出特定X类型的函数重载是否存在。 存在;如果不存在,我想知道基本类型的X是否存在其他函数重载,如果是,在向其传递类型 const X& 的参数时会调用哪一个。

"which"信息应包含基类型,对于上述示例,基类型将是Derived(而不是Base)。

现场示例

您可以复制函数签名并编写自定义特征来检测将调用哪个特征,如下所示:

template <typename T>
struct S {
    static Base mock_foo(const Base&);
    static Derived mock_foo(const Derived&);
    static void mock_foo(...);
    // Base if Base overload will be called, Derived if Derived overload
    // will be called, void if neither
    using type = decltype(mock_foo(std::declval<T>()));
}; 

http://coliru.stacked-crooked.com/a/b72655b770becc15

我不确定是否可以"自动"执行此操作,无需以这种方式键入自定义特征。我猜答案是否定的,它需要核心语言中的某种反射支持。