5

假设我有一个文件 alpha.h:

class Alpha {
public:
    template<typename T> void foo();
};

template<> void Alpha::foo<int>() {}
template<> void Alpha::foo<float>() {}

如果我在多个 cpp 文件中包含 alpha.h 并使用 GCC 4.4 进行编译,它会抱怨存在多个对象文件的多个定义foo<int>foo<float>跨多个对象文件。对我来说很有意义,所以我将最后两行更改为:

template<> extern void Alpha::foo<int>() {}
template<> extern void Alpha::foo<float>() {}

但随后 GCC 说:

显式模板特化不能有存储类

好的......那么我应该如何正确地做到这一点?我担心 C++ 不允许我首先尝试做的事情,在这种情况下,是否有一个好的习语可以完成同样的事情?

4

4 回答 4

10

使用内联关键字

template<> inline void Alpha::foo<int>() {}

或者,在单独的 cpp 文件中提供实现

于 2010-07-16T16:17:32.140 回答
6

您可以转发声明以及内联选项:

// .h
template<> void Alpha::foo<int>();

//.cpp
template<> void Alpha::foo<int>() {}
于 2010-07-16T16:44:29.127 回答
4

从 ODR 的角度来看,完全(显式)专门化的模板不再是模板,因此它与同类的非模板实体遵循相同的 ODR 原则。(我相信该规则有一些例外,但对于我们的目的来说已经足够了)。

在您的情况下,出于 ODR 目的,完全专用的函数模板是普通函数。因此,作为一个普通函数,它应该在头文件中声明并在一个且只有一个实现文件中定义。

于 2010-07-16T17:00:50.773 回答
-1

不需要单独的声明或内联键。PF低于工作代码。

#include<iostream>

class temp
{
public:
    template <class T>
    T add1(T a, T b)
    {
            return (a + b);
    }
};

template<>
std::string temp::add1<std::string>(std::string aa, std::string bb)
{
    return aa+bb;
}

int main()
{
    temp *tc = new temp();
    std::cout << tc->add1<float>(5.7, 4.5) << std::endl;
    std::cout << tc->add1<std::string>("my ","program") << std::endl;
}

输出是:

10.2

我的程序

于 2016-01-05T12:23:52.253 回答