Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不';any_cast函数重载是否会导致歧义?_C++_Templates_Overloading_Boost Any - Fatal编程技术网

C++ 为什么不';any_cast函数重载是否会导致歧义?

C++ 为什么不';any_cast函数重载是否会导致歧义?,c++,templates,overloading,boost-any,C++,Templates,Overloading,Boost Any,Boost的具有: template<typename ValueType> ValueType any_cast(any & operand); template<typename ValueType> inline ValueType any_cast(const any & operand); 模板 ValueType任意_转换(任意操作数(&O); 样板 内联ValueType any_cast(常量any和操作数); (在其他变体中)这种组

Boost的
具有:

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

template<typename ValueType>
inline ValueType any_cast(const any & operand);
模板
ValueType任意_转换(任意操作数(&O);
样板
内联ValueType any_cast(常量any和操作数);
(在其他变体中)这种组合是否应该在调用中引起歧义,例如
boost::any_cast(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;
}
#包括
#包括
样板
ValueType任意_转换(boost::any&操作数)
{
返回boost::任意_转换(操作数);
}
int main()
{
int x=123;
boost::any my_any(x);

std::cout为什么调用会不明确?调用函数的方法是
any
参数是左值。因此,
any
参数要么是
const
限定的,在这种情况下,第二个重载是唯一的潜在匹配,要么不是
const
限定的,在这种情况下,第一个重载是最佳的er匹配(不需要转换,而第二个重载需要从
any&
转换为
any const&
)。如果使用临时
any
调用函数,它可能绑定到右值重载(即,使用
any&
)或者,如果不存在,它可以绑定到
常量
-限定重载,但不能绑定到非
常量
-限定重载,同样,不会造成任何歧义

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

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);
}
名称空间foo{
结构条{};
模板无效条_cast(条&){}
模板无效条(条常数&){}
模板无效条(条&&){}
}
构造任何东西;
模板空心钢筋(无论什么);
int main()
{
foo::bar b;
钢筋混凝土浇筑(b);
}

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

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

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);
}
名称空间foo{
结构条{};
模板无效条_cast(条&){}
模板无效条(条常数&){}
模板无效条(条&&){}
}
构造任何东西;
模板空心钢筋(无论什么);
int main()
{
foo::bar b;
钢筋混凝土浇筑(b);
}

请参阅我的编辑,以解释为什么我认为这应该/可能会导致歧义。@einpoklum:嗯,您为
any\u cast(any&)添加了另一个重载
。您的版本是通过正常查找找到的,
boost
版本是通过依赖于参数的查找找到的。两者都不比另一个好。显然,这会导致错误和歧义。^^^而常量版本出现在列表中的原因可能是编译器在将其从candid列表中删除之前发出诊断ates。这是正确的。我不太理解你答案的第二部分,但你的评论给出了我的答案。请参阅我的编辑,解释为什么我认为这应该/可能会导致歧义。@einpoklum:嗯,你为
任意类型(any&)添加了另一个重载
。您的版本是通过正常查找找到的,
boost
版本是通过依赖于参数的查找找到的。两者都不比另一个好。显然,这会导致错误和歧义。^^^而常量版本出现在列表中的原因可能是编译器在将其从candid列表中删除之前发出诊断我不太明白你答案的第二部分,但你的评论给了我答案。当你用boost::any_cast;
用一个简单的
替换你的全局
any_cast
时会发生什么?main构建吗?当你用bo替换你的全局
any_cast
时会发生什么ost::any_cast;
。main是否构建?