gpt4 book ai didi

c++ - 在模板类型推导之前评估 noexcept 说明符

转载 作者:可可西里 更新时间:2023-11-01 16:39:46 32 4
gpt4 key购买 nike

请看下面的代码:

#include <utility>

struct A {
A(int, int) {}
};

struct tag {};

template <class... Args>
struct is_noexcept {
static constexpr bool value = noexcept(A{std::declval<Args>()...});
};

struct B : A {
//#1
template <class... Args>
B(tag, Args&&... args) noexcept(/*Here*/is_noexcept<Args...>::value) :
A{std::forward<Args>(args)...} {}

//#2
B(int x, int y) : A{x, y} {}
};

int main()
{
B x{0, 0};
}

这段代码似乎被 GCC/Clang 接受,但 MSVC 2017 拒绝了它。似乎 MSVC 编译器在理解 #1 不是适当的重载(由于 tagint 之间的不兼容)之前尝试计算 noexcept 说明符,因此应该丢弃。因此它试图评估 is_noexcept<int>::value并找出noexcept(A{std::declval<int>()})是病式的。由于这不是在直接上下文中发生的,因此这不是 SFINAE 的用武之地,所以是硬错误。

(事实上,我对此不太确定,但我已经确认,如果我在 noexcept(A{std::declval<Args>()...}) 处放置 is_noexcept<Args...>::value 而不是 /*Here*/ 以在直接上下文中产生故障,MSVC 编译器会很高兴丢弃 #1 并调用 #2。这样对吗?)

我怀疑 GCC/Clang 是正确的,而 MSVC 是错误的,但哪个是正确的?

最佳答案

这是一个 MSVC 错误。规则,作为 CWG 1330 的结果, 在 [except.spec]/13是:

An exception specification is considered to be needed when:

  • in an expression, the function is the unique lookup result or the selected member of a set of overloaded functions ([basic.lookup], [over.match], [over.over]);
  • the function is odr-used or, if it appears in an unevaluated operand, would be odr-used if the expression were potentially-evaluated;
  • the exception specification is compared to that of another declaration (e.g., an explicit specialization or an overriding virtual function);
  • the function is defined; or
  • the exception specification is needed for a defaulted special member function that calls the function. [ Note: A defaulted declaration does not require the exception specification of a base member function to be evaluated until the implicit exception specification of the derived function is needed, but an explicit noexcept-specifier needs the implicit exception specification to compare against. — end note ]

The exception specification of a defaulted special member function is evaluated as described above only when needed; similarly, the noexcept-specifier of a specialization of a function template or member function of a class template is instantiated only when needed.

B(tag, Args&&...) 的异常规范不是必需的(我们不满足任何这些项目符号),因此不应实例化它。

另请注意,异常规范中的替换失败不是直接上下文的一部分,并且不会是 SFINAE 友好错误。

关于c++ - 在模板类型推导之前评估 noexcept 说明符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51501156/

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