繁体   English   中英

局部模板指定的编译器错误(C ++)

[英]Compiler errors on partial template speciailzation (c++)

我试图做一个简单的局部模板专门化,但是在g ++ 4.4.7,g ++ 4.8.5,clang ++ 3.8.0上出现错误。 每当我提到编译器错误时,我都是指所有这些的输出,因为它们总是一致的。 我正在使用C ++ 03,没有任何选择地进行编译。

编码:

#include <iostream>

template <typename T, typename X, typename G>
struct A {};

template <typename T, typename X>
struct A<T, X, void> { A() : n(1) {} X n; T b; };

template <typename X>
struct A<X, void, void> { A() : n(2) {} X n; };

int main() {
  A<int, float> one;
  A<int> two;
  std::cout << one.n << " | " << two.n << "\n";
  return 0;
}

问题1:此代码无法编译。 编译器说A<int, float>A<int>是错误的,因为A需要3个模板参数。 为什么?

如果我将原始声明更改为

template <typename T, typename X = void, typename G = void>
struct A {};

代码经过编译,输出为: 1 | 2 1 | 2

发生的情况是,编译器首先将one类型和two类型与未专用的A匹配,但是随后它正确地决定使用希望使用的部分专用类的代码。 但是它不需要默认值。

然后,我决定更改第一个和第二个参数,以更改最后的部分专业化:

template <typename X>
struct A<void, X, void> { A() : n(2) {} X n; };

我希望这不会改变任何东西,但是编译器不同意。 此处报告了这3个之间最清晰的输出:

a.cpp:7:40: error: field has incomplete type 'void'
struct A<T, X, void> { A() : n(1) {} X n; T b; };
                                   ^
a.cpp:14:10: note: in instantiation of template class 'A<int, void, void>'    requested here
  A<int> two;
         ^
1 error generated.

问题2:为什么编译器将two变量视为A的部分专业化实例的一部分,该实例仅专门化一个参数?

请注意,这是“第二次匹配”,因为如果我仅使用1个默认模板参数,则编译器将回过头来抱怨需要3个模板参数这一事实。

谢谢。

问题1:此代码无法编译。 编译器说A<int, float>A<int>是错误的,因为A需要3个模板参数。 为什么?

因为A需要3个模板参数。 您将A声明为:

template <typename T, typename X, typename G>
struct A {};

有没有二维或一模板参数版本的A 有一些版本专门针对某些类型为void的类型,但这仍然是一个参数-并非缺少参数。

添加默认值后, A<int, float>计算结果为A<int, float, void> ,这是有效的实例化-并选择将n设置为1的特殊化。

您误会了专业化的工作原理。 专业化不会更改模板参数的数量。 这只是根据最终模板参数添加特殊功能的一种方式。

问题2:为什么编译器将两个变量视为A的部分专业化实例的一部分,该实例仅专门化一个参数?

我们有三个选择

template <T, X, G>       struct A; // the primary
template <T, X, void>    struct A; // (1)
template <void, X, void> struct A; // (2)

实例化A<int> ,与添加默认参数时的A<int, void, void>相同。 那不匹配(2) -因为那个要求第一个参数为void并且您的参数为int (1)比主要版本更好,因为它更专业。 但是, (1)具有类型X的成员,在这种情况下, X被推导为void (从默认参数),这是不允许的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM