【问题标题】:Template Specialization with Default Value具有默认值的模板特化
【发布时间】:2023-03-20 08:25:01
【问题描述】:

这是我正在使用的代码:

#include <iostream>
#include <type_traits>

using namespace std;

using match_type = void;
using match_type_bad = int;

// version A
template <typename T, typename Attempt = match_type>
struct simple_check : false_type {}; 

// version B
template <typename T>
struct simple_check<T, T> : true_type {}; 

int main() {
  cout << simple_check<match_type>::value << endl;
  cout << simple_check<match_type_bad>::value << endl;
}

具有此模板特化的程序最终具有以下输出:

1
0

我对 C++ 的 tmp 的理解存在混淆,因为我假设输出应该是 1 1

我的理由是:

  1. 使用simple_check&lt;match_type&gt;,它进入版本B,然后扩展为继承自true_typesimple_check&lt;match_type, match_type&gt;。所以1 符合预期。

  2. 不应该同样适用于simple_check&lt;match_type_bad&gt;吗?

  3. 使用此逻辑,simple_check&lt;X&gt; 中的任何类型 X 都应始终为版本 B。

似乎版本 A 的默认值 match_type 在决定版本 B 时正在执行某些规则。

为什么版本 A 会影响版本 B?可能还有别的?

【问题讨论】:

  • 看起来编译器 first 确定模板参数,并且只有 then 检查是否有专门化(因此第一个默认参数用于两者)并且仅首先专业化匹配...

标签: c++ c++11 c++14 c++17 template-meta-programming


【解决方案1】:

当您实例化模板时,它总是在查看专业化之前使用基本版本。它在这里工作,因为第二个模板参数的默认值为match_type

所以

simple_check<match_type> => simple_check<match_type, match_type>
                                                     ^^ this uses the default value

simple_check<match_type_bad> => simple_check<match_type_bad, match_type>
                                                             ^^ again, default value

完成后,编译器会查看特化。
仅当模板参数相同时,特化才有效,因此在第一次检查中,将选择特化而不是基本模板,第二次检查将使用基本模板,因为特化无效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2016-04-06
    相关资源
    最近更新 更多