结构体中的非类型模板参数与别名

问题描述 投票:0回答:1

考虑以下代码片段(C++20、gcc、clang):

template <class>
struct wrapper;

template <int>
struct backend{};

//(1) OK
template <int Arg>
using my_type = backend<Arg>;

//(2) Doesn't compile
//template <int Arg>
//using my_type = backend<Arg + 1>;

//(3) OK
//template <int Arg>
//struct my_type : backend<Arg + 1>{};

template <int Arg>
struct wrapper<my_type<Arg>> {};

int main() {
  [[maybe_unused]] wrapper<my_type<1>> w;
}

为什么 (2) 不能编译而 (3) 可以编译?

Clang 错误:prog.cc:20:12:错误:类模板部分 特化包含无法推导的模板参数; 这种部分专业化永远不会被使用 [-Wunusable-部分专业化] 20 |结构体 包装器 {};

如果您能参考该标准,我将不胜感激。

c++ language-lawyer c++20 template-argument-deduction template-aliases
1个回答
0
投票

匹配部分特化依赖于模板参数推导,而别名模板永远不会被推导。

参见 [temp.alias/2]:

当 template-id 引用别名模板的特化时,它相当于用其 template-argument 替换别名模板的定义类型 id 中的模板参数而获得的关联类型。

[注1: 永远不会推导出别名模板名称。 — 尾注]

示例1(OK):

template <class>
struct wrapper;

template <int>
struct backend{};

template <int Arg>
using my_type = backend<Arg>;

template <int Arg>
struct wrapper<my_type<Arg>> {};
// --> equivalent to:
// struct wrapper<backend<Arg>>

int main() {
  [[maybe_unused]] wrapper<my_type<1>> w;
  // --> equivalent to:
  // [[maybe_unused]] wrapper<backend<1>> w;
}

演绎将

wrapper<backend<1>>
wrapper<backend<Arg>>
进行比较。在此推导的背景下,
Arg
可推导为
1

示例 2(不好):

template <class>
struct wrapper;

template <int Arg>
using my_type = backend<Arg + 1>;

template <int Arg>
struct wrapper<my_type<Arg>> {};
// --> equivalent to:
// struct wrapper<backend<Arg + 1>>

int main() {
  [[maybe_unused]] wrapper<my_type<1>> w;
  // --> equivalent to:
  // [[maybe_unused]] wrapper<backend<2>> w;
}

演绎将

wrapper<backend<2>>
wrapper<backend<Arg + 1>>
进行比较。在此推论的背景下,
Arg
不可推导。

这是因为 [temp.deduct.type/5.4]:

(非推导上下文包括:)非类型模板参数或其中子表达式引用模板参数的数组边界。

示例3(OK):

template <class>
struct wrapper;

template <int>
struct backend{};

template <int Arg>
struct my_type : backend<Arg + 1>{};

template <int Arg>
struct wrapper<my_type<Arg>> {};

int main() {
  [[maybe_unused]] wrapper<my_type<1>> w;
}

演绎将

wrapper<my_type<1>>
wrapper<my_type<Arg>>
进行比较。在此推导的背景下,
Arg
可推导为
1

© www.soinside.com 2019 - 2024. All rights reserved.