C++ 为什么不';any_cast函数重载是否会导致歧义?
Boost的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和操作数); (在其他变体中)这种组
具有:
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是否构建?