gpt4 book ai didi

C++ 概念精简版 : Short-circuiting in concept bodies

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:42:46 24 4
gpt4 key购买 nike

我正在尝试了解尚未合并到标准中的 Concepts Lite TS。我对概念体中短路析取的行为感到困惑。

这是一个小例子:

#include <type_traits>
#include <iostream>

template <typename T, typename ... Ts> concept bool myconcept =
(sizeof...(Ts) == 0) || (std::is_same_v<T, std::common_type_t<Ts...>>);

template <typename ... Ts>
void myfunc(Ts ... args) requires myconcept<int, Ts...> {
(... , (std::cout << args << std::endl));
}

int main() {
myfunc();
return 0;
}

用 gcc 7.1 和 -fconcepts 编译,给出错误:

error: cannot call function 'void myfunc(Ts ...) requires  myconcept<int, Ts ...> [with Ts = {}]'

在这个例子中,std::common_type_t<Ts...>不存在,因为结构 std::common_type<Ts...>没有成员(member)type如果Ts = {} .但是,我认为这应该编译,因为 cppereference.com 关于 concepts and constraints 的文档指出

Disjunctions are evaluated left to right and short-circuited (if the left constraint is satisfied, template argument deduction into the right constraint is not attempted).

sizeof...(Ts) == 0满足,不应在第二个约束和要求 myconcept<int, Ts...> 上尝试模板参数推导应该是满意的。

奇怪的是,将需求直接放入函数声明符会导致程序编译:

#include <type_traits>
#include <iostream>

template <typename ... Ts>
void myfunc(Ts ... args) requires (sizeof...(Ts) == 0) || (std::is_same_v<int, std::common_type_t<Ts...>>) {
(... , (std::cout << args << std::endl));
}

int main() {
myfunc();
return 0;
}

对这种行为有很好的解释吗?谢谢。

最佳答案

出现在cppreference上的外行解释是正确的。从 n4674 draft 中选择措辞也很清楚:

A conjunction is a constraint taking two operands. A conjunction of constraints is satisfied if and only if both operands are satisfied. The satisfaction of a conjunction’s operands are evaluated left-to-right; if the left operand is not satisfied, template arguments are not substituted into the right operand, and the constraint is not satisfied. […]

(来自 17.10.1.1 逻辑运算 [temp.constr.op] §2。)由于所有精确确定我们如何从概念和模板到原子约束的合取或析取的措辞都相当长,我们将坚持外行的解释。

Is there a good explanation for this behavior? Thanks.

在撰写本文时,GCC 的概念实现还处于试验阶段。作为解决方法,您可以将有问题的部分重构为它自己的概念:

template<typename T, typename... Ts>
concept bool refactored = std::is_same_v<T, std::common_type_t<Ts...>>;

template<typename T, typename... Ts>
concept bool myconcept = sizeof...(Ts) == 0 || refactored<T, Ts...>;

Coliru demo

关于C++ 概念精简版 : Short-circuiting in concept bodies,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44895143/

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