gpt4 book ai didi

c++ - 为什么在类声明中定义时允许显式特化类模板成员函数,但在单独定义时却不允许?

转载 作者:行者123 更新时间:2023-11-30 03:01:24 24 4
gpt4 key购买 nike

我看到很多 StackOverflow 帖子都说类模板成员函数的特化在 C++ 中是不合法的,除非封闭类也是特化的。

然而,另一篇文章似乎表明可以特化成员模板函数,只要特化函数的定义出现在模板类的类声明中即可,如下所示:

template<typename T1, typename T2>
class A
{
public:
template<typename TX> TX foo() {return 0;};
template<> T1 foo<T1>() {return 1;}; // provide the specialization's definition within the class declaration: works
//template<> T1 foo<T1>(); // ... switch to this (and provide the definition below), and it's a compile error
};

// This function definition is only present when the commented-out line of code in the class declaration is used
template<typename T1, typename T2>
template<>
T1 A<T1, T2>::foo<T1>()
{
return 1;
}

int main(void)
{
A<int, double> a;
const int n = a.foo<int>(); // When the definition appears inside the class declaration, n is 1 - it works
return 0;
}

正如您从我的代码示例中的注释中看到的那样,当在类声明中提供专用函数的定义时,代码构建没有错误,并且运行成功,n 的值> 正如预期的那样,main() 函数中的值为 1

但是,当将专用函数定义移动到类声明之外,但保持不变时,如图所示,编译器会发出其他帖子已经指出的错误;在我的例子中 (Visual Studio 2010),错误是模板成员的显式特化必须是显式特化的成员

我的问题是这样的。如果类模板中的成员函数的显式特化是不允许的,除非封闭的模板类也是特化的,那么如果在类声明中提供定义,为什么它在我的示例代码中起作用?

最佳答案

由于不同的原因,这两个版本都不应该编译。

在第一种情况下,特化必须出现在命名空间级别,这意味着类定义中提供的特化应该被编译器拒绝。

在第二种情况下,特化的位置是正确的,但是要提供成员函数的特化(函数的特化必须始终是完整的,绝不是部分的),您还需要修复封闭的模板类参数。也就是说,无论使用哪种类型 T1T2 来实例化,您都不能将 foo 专门化为类型 X封闭的模板。您可以(可能不是您想要的)提供所有参数固定的特化:

template <> template <>
int A<int, double>::foo<int>() { return 5; }

您可以使用的替代方案是:

  • 提供非模板重载,而不是模板特化(在大多数情况下,提供重载比特化更有意义,但这里可能不是这种情况,因为您不能对返回类型进行重载。
  • 将函数移动到不同的模板类,然后在那里执行部分特化。
  • 执行第一个选项的变体:提供一个单一的非专用模板供客户端使用,该模板转发到为其提供不同重载的内部函数

例子:

// inside class template:
private:
template <typename T> T foo_impl( T* _ ) {...} // generic
T1 foo_impl( T1 * _ ) {...} // concrete
public:
template <typename T> T foo() {
return foo_impl( (T*)0 );
}

通过这种方式,您可以将仅在返回类型上的模板转换为对重载函数的调用,并且可以让编译器为您解决问题。

关于c++ - 为什么在类声明中定义时允许显式特化类模板成员函数,但在单独定义时却不允许?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11085550/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com