gpt4 book ai didi

c++ - 部分模板特化的编译器错误 (c++)

转载 作者:搜寻专家 更新时间:2023-10-31 00:10:53 25 4
gpt4 key购买 nike

我正在尝试进行简单的部分模板特化,但在 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 .

发生的事情是编译器在第一步中匹配onetwo输入非专业 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 variable 是 A 的部分特化的一个实例,它只特化了一个参数?

请注意这是“第二次匹配”,因为如果我只使用 1 个默认模板参数,编译器将返回提示需要 3 个模板参数这一事实。

谢谢。

最佳答案

Question 1: This code fails to compile. The compilers say that A<int, float> and A<int> are wrong as A requires 3 templates parameters. Why?

因为 A需要 3 个模板参数。你声明了 A作为:

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

A 没有两个或一个模板参数版本.有专门针对某些类型的版本 void ,但这仍然是一个参数 - 而不是缺少参数。

添加默认值后,A<int, float>评估为 A<int, float, void> ,这是一个有效的实例化 - 并选择设置 n 的特化到 1。

您误解了特化的运作方式。特化不会改变模板参数的数量。这只是一种根据模板参数最终成为什么来添加特殊功能的方法。

Question 2: Why are the compilers considering the two variable an instance of the partial specialization of A that specializes only one argument?

我们有三个选择

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 (来自默认参数),这是不允许的。

关于c++ - 部分模板特化的编译器错误 (c++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35948475/

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