首次使用之前必须明确专业化

Tyg*_*g13 4 c++ templates template-specialization

我需要能够将存根代码插入到模板函数中,其中存根代码是专门的。如果我使用像这样的蹦床,大多数编译器都允许这样做

template <class T>
T foo(T t) {
   if(Stub<T>::enabled) {
      return Stub<T>::stub(t);
   }
   /* actual code here */
}

/* use of foo occurs here */

template <>
int Stub<int>::stub(int) { /* stub code */ }
Run Code Online (Sandbox Code Playgroud)

至少这适用于大多数版本的 GCC、clang 和 MSVC。有一些旧版本的 GCC 和 GCC 派生编译器不接受这一点,并抱怨Stub<T>::stub首次使用后无法发生显式特化。

我的问题是 - 这些编译器是否有解决方法 - 如果没有,就标准而言这是允许的吗?或者我是否依赖 GCC/Clang/MSVC 来“做正确的事”?

Gui*_*cot 5

这是 ODR 问题。我认为不需要诊断,但代码仍然格式不正确。

要解决此问题,您可以在定义专业化之前声明它:

template <class T>
T foo(T t) {
   if(Stub<T>::enabled) {
      return Stub<T>::stub(t);
   }
   /* actual code here */
}

/* declaration */
template <>
int Stub<int>::stub(int);

/* use of foo occurs here */

template <>
int Stub<int>::stub(int) { /* stub code */ }
Run Code Online (Sandbox Code Playgroud)

为什么我认为这是 ODR 问题。

查看example1example2。两者都以相同的方式使用模板。一个是内联主模板,另一个是调用缺少的专业化,因为专业化可能位于某个地方的另一个翻译单元中。

将特化添加到示例 1 中的另一个翻译单元将是 IFNDR,这确实很难调试。