CRTP 的不明确过载
Ambiguous overload with CRTP
当我使用 CRTP(奇怪的重复模板模式(时,当我使用基类(显式(可强制转换为bool
时,我收到编译器错误,并且也可以转换为Derived
类型。 如果我尝试使用 ostream
将Derived
类型输出为右值,则会发生编译器错误。 例如:
#include <iostream>
using namespace std;
template <class Object>
class Base
{
private:
typedef void (Base::*explicit_bool_type)() const;
void explicit_bool_idiom() const { }
public:
operator explicit_bool_type() const
{
return &Base::explicit_bool_idiom;
}
operator Object& ()
{
return Object();
}
operator const Object& () const
{
return Object();
}
};
class Derived : public Base<Derived>
{
public:
friend std::ostream& operator << (std::ostream& os, const Derived& d)
{
os << "abc";
return os;
}
};
int main()
{
std::cout << Derived() << std::endl;
}
这给出了编译器错误:
test2.cpp:42: error: ambiguous overload for ‘operator<<’ in ‘std::cout << Derived()’
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/ostream.tcc:102: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]
test2.cpp:32: note: std::ostream& operator<<(std::ostream&, const Derived&)
问:这是一个编译器错误吗? 我怀疑可能是,因为它只发生在旧版本的 GCC 上,比如 GCC 4.1.2。 使用 GCC 4.8.2,它可以正常工作。 不幸的是,我需要让它在较旧的编译器上运行。 如果我为Derived
重载std::ostream& operator <<
,它可以工作。 (如果我将Derived
的实例输出为左值,它也有效。
我不确定为什么编译器认为std::ostream::operator << (bool)
是一个同样有效的候选者。
另外,我知道明确的布尔习语在 C++11 中已经过时了 - 同样,需要在较旧的编译器上使用它。
有没有办法在不使Derived
std::ostream& operator <<
过载的情况下解决歧义?
它确实似乎是 g++ 4.1 中的一个错误。它至少在 4.2.3 及更高版本中有效。
此外,如果删除隐式转换为explicit_bool_type
或两者Object&
转换,则编译良好。我强烈认为隐式下铸是一个坏主意(假设您的实际实现实际上并没有通过引用返回堆栈变量(,并建议删除这些运算符,这样还有修复编译错误的额外好处。
相关文章:
- Visual C++(VS2017)中用户定义的转换不明确
- 重载类方法的不明确调用
- 为函数定义符号不明确的指针参数
- 父类的私有函数会导致对具有相同名称和相似参数的子类中的公共函数的不明确调用
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- C++ 编译器错误:P1LinkedList.cpp:145:错误:重载的"to_string(int&)"调用不明确
- 对重载函数find_first_not_of的不明确调用
- 不明确的成员模板查找
- gcc出现不明确的模板实例化错误
- 调用'Node'构造函数是不明确的
- 如何解决不明确的运算符过载问题?
- 使用 nullptr 调用重载方法是不明确的
- "fpclassify":对重载函数的不明确调用
- 对"列表"的引用不明确,包括头文件
- 删除全局隐式函数 - 避免使用不明确的运算符
- 当接收到不明确的规范时,表示图的邻接列表的数据结构
- "byte":使用Crypto++和Windows SDK时出现不明确的符号错误
- 使用 std::iterator_traits<> 时编译时错误不明确
- 不明确的函数模板
- CRTP 的不明确过载