C++ 如何解决用文本0和指针调用重载函数的歧义性
我很确定这一定已经在这里了,但我没有找到多少关于如何解决此类问题的信息(不考虑电话): 给定两个重载,我希望使用文本为0的函数调用始终调用无符号int版本:C++ 如何解决用文本0和指针调用重载函数的歧义性,c++,templates,overloading,overload-resolution,C++,Templates,Overloading,Overload Resolution,我很确定这一定已经在这里了,但我没有找到多少关于如何解决此类问题的信息(不考虑电话): 给定两个重载,我希望使用文本为0的函数调用始终调用无符号int版本: void func( unsigned int ) { cout << "unsigned int" << endl; } void func( void * ) { cout << "void *" << endl; } func( 0 ); // error: ambi
void func( unsigned int ) {
cout << "unsigned int" << endl;
}
void func( void * ) {
cout << "void *" << endl;
}
func( 0 ); // error: ambiguous call
void func(无符号整数){
库特
1) 一般来说,有没有推荐的方法
是的,我会像你在2)中那样做。我不认为2)工作的原因有任何更深层次的含义。类型int
根本不匹配t*
,因此它无法找到t
。因此它会忽略模板。你在2)中所做的工作,并且可能是更好的方法
在不希望更改函数的情况下,可以执行显式强制转换以向编译器提供提示:
func((void *) 0);
func((unsigned int) 0);
我建议您看看C++0x中的空指针(请参阅)。它定义了一个表示任何类型的空指针的类。您刚才给出的示例实际上是一个促使包含nullptr_t(类)/nullptr(值)的示例它实际上允许您在需要无符号int版本时放入0,在需要另一个版本时放入nullptr,从而消除此调用的歧义
您可以在一个小实用程序类中实现这个技巧,直到您的编译器支持它为止(或者如果您的编译器实现了下一个标准的这一部分,就使用它)
1) 一般来说,有没有推荐的方法
问题很简单,文本0
是int
,而不是unsigned int
,并且存在从int
到unsigned int
以及从int
到void*
的有效转换。我不能说有推荐的方法来处理这个问题。除了你已经用过的方法之外找到时,还可以添加另一个重载:
void func(int i)
{
assert(i >= 0);
return func(static_cast<unsigned int>(i));
}
void func(int i)
{
断言(i>=0);
返回函数(静态_cast(i));
}
2) 按照下面的方法进行操作是否有任何问题?原因是什么
void func( unsigned int ) {
cout << "unsigned int" << endl;
}
template <typename T>
void func( T * ) {
static_assert( std::is_same<T, void>::value, "only void pointers allowed" );
cout << "void *" << endl;
}
func( 0 ); // calls func( unsigned int )!
模板技巧之所以有效,是因为用于解析重载函数调用的规则以及具有模板版本的函数的规则被设计为更喜欢重载函数的非模板版本。“在需要未签名的int版本时放置0”-但我认为func(0)
在C++0x中仍然是不明确的。无论是int
到unsigned int
还是指向void*
或tostd::nullptr\u t
的空指针常量都是转换,在重载解析方面两者都不比另一个好。我在开始时是这样认为的,但我建议您参考以下内容:(阅读请参阅nullptr如何优雅地解决前面显示的重载解决问题:“部分)nullptr
是一个类似指针的对象,但这并不意味着int
s不再隐式地转换为指针。这意味着当您编写nullptr
时,您实际上并不是在以迂回的方式编写0
。@Max,我同意,但Alp提供的链接表明情况并非如此。它说0将不再转换t指向指针(或至少具有较低的重载优先级),但我怀疑这实际上会破坏很多代码。谢谢,但这对我没有帮助,因为我希望将普通文本0始终传递给非指针重载。实际用途是重载运算符[],它允许按索引和字符进行索引*(对于字符串文字)其中nullptr永远不是有效参数。非常简单的解释…现在你说了,很明显它为什么工作。