在不使用特化语法的情况下,为不同类型实现模板类的方法是否有效?

Sco*_*ham 13 c++

我是代码审查同事代码并发现:

头文件:

template<class T>
class MyClass
{
  void Execute();
}
Run Code Online (Sandbox Code Playgroud)

Cpp文件:

void MyClass<int>::Execute()
{
  // something
}

void MyClass<string>::Execute()
{
  // something else
}
Run Code Online (Sandbox Code Playgroud)

代码专门用于函数,但不使用模板特化语法.我猜它工作正常,但它有效吗?

Luc*_*ore 7

是的,专门化模板类的方法是完全有效的.

但是你的语法错了,它应该是:(对不起,没看到你template<>最初错过了.只是假设它在那里,并认为你在询问有关成员函数的专业化.)

template<>
void MyClass<int>::Execute()
{
  // something
}
template<>
void MyClass<string>::Execute()
{
  // something else
}
Run Code Online (Sandbox Code Playgroud)

您只需要在标题中声明这些.如果您也在标题中实现它们,则需要标记它们inline以防止多重定义.

调用方法时,调用最适合调用的版本.否则,默认.

在您的情况下,如果您使用类专门化模板X并尝试调用Execute,您将收到链接器错误,因为您没有提供默认实现,也没有提供for Execute的特化X.


Ker*_* SB 5

问题已经得到解答,但让我提请注意三个案例之间的微妙差异.

案例1:专业化

标题:

template <typename T> struct Foo
{
    void f() { /* stuff */ }
};

template <> void Foo<int>::f();
Run Code Online (Sandbox Code Playgroud)

资源:

template <> void Foo<int>::f() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Foo<T>::f()可以调用任何T.一般情况的定义是从模板自动生成的; 定义Foo<int>::f()是提供的定义.在标题中具有专门化警告每个消费翻译单元要查找单独的符号,而不是使用模板.


案例2:定义

标题:

template <typename T> struct Foo
{
    void f();
};
Run Code Online (Sandbox Code Playgroud)

资源:

template <> void Foo<int>::f() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只能 Foo<int>::f()使用; 其他一切都会导致链接器错误.由于模板中没有函数的定义,因此模板的每次使用都将导致发出新符号,并且Foo<int>::f()所显示的翻译单元仅提供一个符号.


案例3:明显的错误

标题:

template <typename T> struct Foo
{
    void f() { /* stuff */ }
};
Run Code Online (Sandbox Code Playgroud)

资源:

template <> void Foo<int>::f() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

这违反了单定义规则,因为现在有多个定义Foo<int>::f().


APr*_*mer 4

这是显式专业化的旧语法。但令我惊讶的是,您使用的编译器仍然接受它(g++ 在 4.0 左右停止)。为了保持一致,您需要在专业化前面加上前缀template <>.