【问题标题】:SFINAE to detect the explicitness of a CTAD deduction guideSFINAE 检测 CTAD 扣除指南的明确性
【发布时间】:2021-10-15 22:14:23
【问题描述】:

C++17 CTAD(类模板参数推导)鲜为人知的特性:可以将用户定义的推导指南标记为explicit。 (Godbolt.)

template<class T> struct A { A(int); };           A(int) -> A<int>;
template<class T> struct B { B(int); };  explicit B(int) -> B<int>;

A<int> a = 1;  // OK, constructor of A<int> is implicit
B<int> b = 1;  // OK, constructor of B<int> is implicit

auto a = A(1);  // OK, deduction guide of A exists
auto b = B(1);  // OK, deduction guide of B exists

A a = 1;  // OK, deduction guide of A is non-explicit
B b = 1;  // ERROR!! deduction guide of B is explicit

因此,类模板AB 具有明显不同的行为。 我想写一个单元测试,static_asserts 我的一个模板的行为类似于B,而不是A

static_assert(!has_properly_explicit_deduction_guide_v<A>);
static_assert(has_properly_explicit_deduction_guide_v<B>);

这在 C++17 和/或 C++20 和/或“C++future”中是否可行?

【问题讨论】:

标签: c++ c++17 c++20 template-meta-programming ctad


【解决方案1】:

没有。

不能检查声明,所以不能检查A a = 1;B b = 1;的有效性

并且类模板参数推导在任何其他复制初始化上下文中都无效。因此,虽然您可以通过查看表达式 [](To){}(from) 是否有效来检查“隐式可转换”,但您不能通过查看表达式 [](A){}(1) 是否有效来检查“隐式类模板参数演绎”,因为您不能只写 @ 987654328@那里。

您唯一可以检查的是A(1) 是否有效,但这是直接初始化,因此无法验证explicitness。

【讨论】:

  • godbolt.org/z/P3bdvYh17 有任何其他想法吗? NTTP 是 CTAD 有效的另一种情况。但是 (1) 这仅适用于 NTTP 友好类型,这显然对 general 没有帮助,并且 (2) 这里似乎存在实现分歧。
  • @Quuxplusone 你可以这样做much simpler。不过,gcc 在这种情况下允许显式推导指南。是的,这不是一个通用的解决方案。
  • .. 现在是#101833
【解决方案2】:

目前,根据[dcl.type.class.deduct],推导类类型的占位符可以出现在:

  • 变量的初始化声明;
  • 一个新表达式;
  • 显式类型转换(功能符号);或
  • 非类型模板参数 [NTTP]。

其中第一个不是 SFINAE-able (无论是经典的还是在requires 子句中),因为它是一个声明而不是一个表达式;接下来的两个调用直接初始化,而不是复制初始化;最后一个仅适用于具有constexpr 构造函数的结构类型(尽管这在标准中并不是特别清楚)。

写。未来的方向,早在 2018 年,Mike Spertus 就在函数模板参数上寻找 CTAD:Improving function templates with Class Template Argument DeductionHow to make Terse Notation soar with Class Template Argument Deduction。从那以后,这方面没有太多动静,但也许它可以复活。

【讨论】:

    猜你喜欢
    • 2020-11-30
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多