本文介绍了跨文件共享的C ++模板专业化定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在"extra.h"中定义的模板类"Extra",它具有一个函数"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"的不同文件的排列方式?下面是我的代码.谢谢!

I have a template class "Extra," defined in "extra.h," with a function "doSomething," and I have defined two specializations of "doSomething." Two different functions create objects of type "Extra," each with a different type parameter, and each calls a different one of the specializations. The two client functions, "client1" and "client2," are defined in two files, "client1.cpp" and "client2.cpp," respectively. In a third file, "main" calls "client1" and then "client2." Now, "client1.cpp" and "client2.cpp" both #include "extra.h." I get a linker error that "doSomething" has (2) multiple definitions. Naturally, if I put the defintions of "client1" and "client2" into a single source file, I do not have this problem. Is there any way that I can preserve my arrangement of distinct files for "client1" and "client2"? Below is my code. Thank you!

// 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;
}

在这里,为了完整起见,这是我的链接器错误:

And here, for completness, is my linker error:

$ 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

推荐答案

您需要内联标记 doSomething :

template <> inline int Extra<int>::doSomething(int input)
{
    return input * m_value;
}

template <> inline double Extra<double>::doSomething(double input)
{
    return input + m_value;
}

这篇关于跨文件共享的C ++模板专业化定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 03:56