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

时间:2016-07-18 06:21:00

标签: c++ templates c++14 overload-resolution

我有免费的函数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, "");
    }
};

现在假设以下类层次结构fooBase的{​​{1}}重载:

Derived

如何确定在调用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的参数传递给它时将调用哪一个。

“which”信息应包含基本类型,以上示例为const X&(而不是Derived)。

live example

1 个答案:

答案 0 :(得分:0)

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

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

我不确定是否可以“自动”,这样做而不用这种方式输入自定义特征。我猜这个答案是否定的,它需要在核心语言中提供某种反射支持。