函数模板重载 - 排序

时间:2014-01-30 13:11:49

标签: c++ function templates

我不明白。我知道函数模板是邪恶的,但在这种情况下我们必须使用它。所以这不是问题。我们有一个使用模板操作符功能的存档。对象/值类型的特化遵循模板函数声明/定义之后:

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)编译器确实......

非常感谢

2 个答案:

答案 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;
}