我不明白。我知道函数模板是邪恶的,但在这种情况下我们必须使用它。所以这不是问题。我们有一个使用模板操作符功能的存档。对象/值类型的特化遵循模板函数声明/定义之后:
class BaseArchive
{
public:
BaseArchive() {}
virtual ~BaseArchive();
template< typename T >
BaseArchive & operator<<(const T &t)
{
::operator<<(*this, t);
return *this;
}
};
BaseArchive & operator<<(BaseArchive &ar, const int & i)
{
return ar;
}
class StdArchive : public BaseArchive
{
public:
StdArchive();
template< typename T >
StdArchive & operator<<(const T &t)
{
::operator<<(*this, t);
return *this;
}
};
int main()
{
BaseArchive ar;
int i = 7;
ar << i;
}
对于此示例,我们收到错误:
::运营商LT;&LT;尚未宣布
这个可以通过
的前向声明来修复class BaseArchive;
BaseArchive & operator<<(BaseArchive &ar, const int & i);
class Archive { ...
到目前为止一切顺利。但之后一些类为归档定义了自己的::运算符,因此很难甚至不可能确保特定的运算符声明总是在archive-header-include之前发生,甚至我们也不想使用全局运算符inlcude文件。 / p>
知道如何解决这个问题和/或解释为什么会出现这种错误?像往常一样,VS编译器并不关心这一点,但minGW(gcc)编译器确实......
非常感谢答案 0 :(得分:4)
首先,功能模板不是邪恶的。你在哪里得到这个想法?
其次,您的设置没有意义。为什么成员函数模板operator <<
存在?除了转发到全局版本之外它什么都不做,并且因为它使用了显式限定,所以ADL不适用。
只需删除成员函数模板并依赖ADL即可找到正确的operator<<
。
答案 1 :(得分:0)
为什么没有独立的运营商和转发:
#include<iostream>
struct BaseArchive {};
BaseArchive & operator<<(BaseArchive &ar, const int & i)
{
std::cout << "BaseArchive\n";
return ar;
}
struct StdArchive : BaseArchive {};
template< typename T >
StdArchive& operator<<(StdArchive& archive, const T &t)
{
std::cout << "StdArchive\n";
operator << (static_cast<BaseArchive&>(archive), t);
return archive;
}
int main()
{
StdArchive ar;
ar << 7;
}