【问题标题】:How do I define an explicit specialization of a template member function in .cpp file如何在 .cpp 文件中定义模板成员函数的显式特化
【发布时间】:2020-02-21 11:48:59
【问题描述】:

我正在尝试将模板成员函数的显式特化移动到 .cpp 文件,但链接器一直说“未解析的外部符号”。

Foo.hpp

struct Color {};

class Foo
{
public:
  template<typename T> int add(T b);
  template<> int add(Color b);
};

template<typename T>
int Foo::add(T b)
{
  return 0;
}

Foo.cpp

#include "Foo.hpp"

template<>
int Foo::add(Color b)
{
  return 0;
}
template int Foo::add(Color b);

Bar.cpp

#include "Foo.hpp"

void f() {
  Foo dbg;
  dbg.add(5);
  dbg.add(Color());
}

我尝试在 Foo.cpp 中显式实例化成员函数。为什么这没有任何效果?

我知道两种解决方案:我可以将 int Foo::add(Color) 的定义移动到 .hpp 中,并将其标记为内联。或者我可以像这样在 Foo.cpp 中强制实例化:

void dummy() {
  Foo().add(Color());
}

我怎么不能用template int Foo::add(Color b)来实例化函数呢?我是否使用了错误的语法?

【问题讨论】:

  • 只创建一个没有函数模板特化的函数重载,即int add(Color)
  • @aep 是的,这行得通,谢谢。但。为什么。我很困惑。那么,明确的完全专业化有什么意义呢?
  • 从编译器的角度来看,函数特化和重载是不同的。我不想详述,但请关注stackoverflow.com/questions/7108033/…
  • 我必须承认我偶然发现了和你一样的语法问题。在回答的帮助下,我运行了sample。而且,是的,你是对的。模板特化可以在翻译单元中。 (链接器只能选择一种可能的实现。)我的错...... :-((但是,嘿,我学到了一些东西。):-)
  • @Scheff 一切都好。如果你能从我的无知中学到一些东西,那么 SO 就达到了它的目的。 :)

标签: c++


【解决方案1】:

我不确定,但我认为您正在尝试这样做。

在 Foo.h 中

struct Color {};

class Foo
{
public:
    template<typename T> int add(T b);
};

// declare, but do not implement, specialization
template<>
int Foo::add<Color>(Color c);

// general implementation
template<typename T>
int Foo::add(T b)
{
    return 0;
}

在 Foo.cpp 中

#include "Foo.h"

// explicitly implement
template<>
int Foo::add<Color>(Color b)
{
    return 42;
}

最后,main.cpp

#include "Foo.h"

int main()
{
    Foo f;
    std::cout << f.add(Color()) << '\n';
}

输出

42

【讨论】:

  • 哦,所以我使用了错误的语法来声明特化!谢谢!我今天学到了一些新东西。
猜你喜欢
  • 2011-07-27
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多