1

Boost<boost/any.hpp>有:

template<typename ValueType>
ValueType any_cast(any & operand);

template<typename ValueType>
inline ValueType any_cast(const any & operand);

(在其他变体中。)这种组合不应该在调用中引起歧义boost::any_cast<int>(my_any);吗?

我问是因为如果我写这个程序:

#include <boost/any.hpp>
#include <iostream>

template<typename ValueType>
ValueType any_cast(boost::any & operand)
{
        return boost::any_cast<ValueType>(operand);
}

int main()
{
        int x = 123;
        boost::any my_any(x);
        std::cout << "my_any = " << any_cast<int>(my_any) << "\n";
        return 0;
}

我确实收到了关于歧义的投诉

g++ -std=c++14 -O3 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:14:57: error: call of overloaded 'any_cast(boost::any&)' is ambiguous
         std::cout << "my_any = " << any_cast<int>(my_any) << "\n";
                                                         ^
main.cpp:5:11: note: candidate: ValueType any_cast(boost::any&) [with ValueType = int]
 ValueType any_cast(boost::any & operand)
           ^~~~~~~~
In file included from main.cpp:1:0:
/usr/local/include/boost/any.hpp:281:22: note: candidate: ValueType boost::any_cast(const boost::any&) [with ValueType = int]
     inline ValueType any_cast(const any & operand)
                      ^~~~~~~~
/usr/local/include/boost/any.hpp:258:15: note: candidate: ValueType boost::any_cast(boost::any&) [with ValueType = int]
     ValueType any_cast(any & operand)
               ^~~~~~~~
4

1 回答 1

5

为什么电话会模棱两可?你调用函数的方式any参数是一个左值。因此,any参数要么是const-qualified 在这种情况下第二个重载是唯一的潜在匹配,要么它不是const-qualified 在这种情况下第一个重载是更好的匹配(不需要转换,而第二个重载需要转换从any&any const&)。如果您使用临时 调用函数any,它可以绑定到右值重载(即,any&&使用 ),或者,如果不存在,它可以绑定到const-qualified 重载,但不能绑定到 non - constqualified 重载,同样,不是造成任何歧义。

实际上,这里发生了一些有趣的事情:如果没有全局命名空间中的重载,则无法使用使用显式模板参数的函数!但是,只要存在任何功能模板,即使是不匹配的,也可以使用!这是一个例子:

namespace foo {
    struct bar {};

    template <typename T> void bar_cast(bar&) {}
    template <typename T> void bar_cast(bar const&) {}
    template <typename T> void bar_cast(bar&&) {}
}

struct whatever;
template <typename T> void bar_cast(whatever);

int main()
{
    foo::bar b;
    bar_cast<int>(b);
}
于 2016-12-26T17:16:41.977 回答