【问题标题】:c++ template specialization - linker error multiple definitionsc ++模板专业化 - 链接器错误多个定义
【发布时间】:2011-07-24 03:02:29
【问题描述】:

我今天的第三个问题 ;-),但我对 c++ 模板编程和运算符重载真的很陌生。

我正在尝试以下方法:

终端日志.hh

//snipped code

class Terminallog {
public:

    Terminallog();
    Terminallog(int);
    virtual ~Terminallog();

    template <class T>
    Terminallog & operator<<(const T &v);
    template <class T>
    Terminallog & operator<<(const std::vector<T> &v);
    template <class T>
    Terminallog & operator<<(const T v[]);
    Terminallog & operator<<(const char v[]);

//snipped code
};

//snipped code
template <class T>
Terminallog &Terminallog::operator<<(const T &v) {
    std::cout << std::endl;
    this->indent();
    std::cout << v;
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> &v) {
    for (unsigned int i = 0; i < v.size(); i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << "Element " << i << ": " << v.at(i);
    }
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const T v[]) {
    unsigned int elements = sizeof (v) / sizeof (v[0]);
    for (unsigned int i = 0; i < elements; i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << "Element " << i << ": " << v[i];
    }
    return *this;
}

Terminallog &Terminallog::operator<<(const char v[]) {
    std::cout << std::endl;
    this->indent();
    std::cout << v;
    return *this;
}
//snipped code

试图编译这段代码,它给了我一个链接器错误:

g++ src/terminallog.cc inc/terminallog.hh testmain.cpp -o test -Wall -Werror 
/tmp/ccifyOpr.o: In function `Terminallog::operator<<(char const*)':
testmain.cpp:(.text+0x0): multiple definition of `Terminallog::operator<<(char const*)'
/tmp/cccnEZlA.o:terminallog.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

因此,我目前正在将头撞在墙上,寻找解决方案。但我在墙上找不到...

如果有人能告诉我我的错误,那就太好了

非常感谢

ftiaronsem

【问题讨论】:

    标签: c++ template-specialization


    【解决方案1】:

    这个函数

    Terminallog &Terminallog::operator<<(const char v[]) {
        std::cout << std::endl;
        this->indent();
        std::cout << v;
        return *this;
    }
    

    不是模板,而是常规的成员函数。如果此 .h 文件包含在多个 .cpp 过滤器中,则会导致您看到的多重定义错误。如果你声明它inline,编译器将允许多个定义并且你的错误应该被修复。

    inline
    Terminallog &Terminallog::operator<<(const char v[]) {
    

    【讨论】:

    • 哇,完全正确。太感谢了。但我还有一个问题:我在那个头文件中有一个包含保护。因此,它应该只包含一次。为什么我仍然收到此错误?
    • @fitaronsem:这里有一个slightly confusing article,它可能对你有所帮助。
    • @Pablo:文件的扩展名与它几乎没有关系。它是关于翻译单元的,它可能不限于一个“.cpp 文件”。
    • @Pablo, @Tomalak:感谢你们两位出色的 cmets,他们同样有用。我对翻译单元和类似的编译器一无所知。因此,pablos 的评论对我很有帮助。但是,该文章的链接也很棒。它让我了解了为什么我会遇到一些错误。谢谢你们俩的这些cmets。 P.S.:我将尝试在网上搜索以找出编译单元可能是什么,但那是明天的,我现在要睡觉;-)。
    • @fiaronsem:编译单元是编译器在预处理器完成其工作后看到的。粗略地说,它是您的源文件(通常是 .c.cpp),其中包含的所有标题都被直接复制和粘贴,并且所有宏都展开了。
    猜你喜欢
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 2020-07-18
    • 2011-10-06
    • 2018-09-28
    • 1970-01-01
    相关资源
    最近更新 更多