【发布时间】:2017-10-20 06:43:32
【问题描述】:
我有一个模板类“Extra”,定义在“extra.h”中,带有一个函数“doSomething”,并且我定义了“doSomething”的两个特化。两个不同的函数创建“Extra”类型的对象,每个对象都有一个不同的类型参数,并且每个都调用一个不同的特化。两个客户端函数“client1”和“client2”分别在两个文件“client1.cpp”和“client2.cpp”中定义。在第三个文件中,“main”调用“client1”,然后调用“client2”。现在,“client1.cpp”和“client2.cpp”都#include“extra.h”。我收到“doSomething”有 (2) 多个定义的链接器错误。当然,如果我将“client1”和“client2”的定义放在一个源文件中,我就不会有这个问题。有什么方法可以保留“client1”和“client2”的不同文件的排列?下面是我的代码。谢谢!
// extra.h
#ifndef EXTRA_H
#define EXTRA_H
template <typename T>
class Extra
{
public:
Extra(T);
~Extra();
T doSomething(T);
private:
Extra() {}
T m_value;
};
template <typename T> Extra<T>::Extra(T input) : m_value{input} {}
template <typename T> Extra<T>::~Extra() {}
template <> int Extra<int>::doSomething(int input)
{
return input * m_value;
}
template <> double Extra<double>::doSomething(double input)
{
return input + m_value;
}
template <typename T> T Extra<T>::doSomething(T input)
{
return input;
}
#endif
// client1.cpp
#include "extra.h"
#include <iostream>
void client1()
{
std::cout << "In client1." << std::endl;
Extra<int> extra(2);
int res = extra.doSomething(3);
std::cout << "Value: " << res << std::endl;
}
// client2.cpp
#include "extra.h"
#include <iostream>
void client2()
{
std::cout << "In client2." << std::endl;
Extra<double> extra(2.0);
double res = extra.doSomething(2.0);
std::cout << "Value: " << res << std::endl;
}
// main.cpp
#include <iostream>
void client1();
void client2();
int main()
{
std::cout << "In main." << std::endl;
client1();
client2();
return 0;
}
为了完整起见,这里是我的链接器错误:
$ g++ -std=c++11 -o client client1.cpp client2.cpp main.cpp
duplicate symbol __ZN5ExtraIiE11doSomethingEi in:
/var/folders/mf/jdvfkpms609206zpz8x5237r0000gn/T/client1-6fa7ed.o
/var/folders/mf/jdvfkpms609206zpz8x5237r0000gn/T/client2-387444.o
duplicate symbol __ZN5ExtraIdE11doSomethingEd in:
/var/folders/mf/jdvfkpms609206zpz8x5237r0000gn/T/client1-6fa7ed.o
/var/folders/mf/jdvfkpms609206zpz8x5237r0000gn/T/client2-387444.o
ld: 2 duplicate symbols for architecture x86_64
【问题讨论】:
标签: c++ templates linker linker-errors