【问题标题】:C++ Concepts Lite: Short-circuiting in concept bodiesC++ Concepts Lite:概念体中的短路
【发布时间】:2017-07-03 23:56:52
【问题描述】:

我正在尝试了解尚未合并到标准中的 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&lt;Ts...&gt; 不存在,因为如果 Ts = {} 结构 std::common_type&lt;Ts...&gt; 没有成员 type。但是,我认为这应该可以编译,因为 cppereference.com 在concepts and constraints 上的文档指出

从左到右评估析取并短路(如果满足左约束,则不尝试将模板参数推导到右约束中)。

由于满足sizeof...(Ts) == 0,因此不应在第二个约束上尝试模板参数推导,并且应满足要求myconcept&lt;int, Ts...&gt;

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

#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;
}

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

【问题讨论】:

  • "Concepts Lite TS 尚未合并到标准中" 我在哪里可以找到此信息?我最后的信息是它没有被接受......

标签: c++ c++-concepts


【解决方案1】:

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

合取是采用两个操作数的约束。当且仅当两个操作数都满足时,才满足约束的合取。从左到右评估合取操作数的满意度;如果不满足左操作数,则模板参数不会替换为右操作数,并且不满足约束。 […]

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

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

在撰写本文时,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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多