c++ - 使用参数类型的值在尾随返回中需要 decltype

标签 c++ templates language-lawyer c++17

在试图理解 c++17 兼容代码时,我对以下代码感到困惑 该函数使用 integral_constant 类型参数中的值 尾随返回类型。 (请随时纠正我的术语等,努力学习)

下面展示了两个简单的版本,有和没有 decltype 尾随返回中的参数。

使用编译器资源管理器 https://godbolt.org/z/vqmzhu

第一个 (bool_from1) 编译成功
MSVC 15.8;/std:c++17,/O2,/permissive-
以及 clang 8.7.0.0 和 gcc 8.2; -std=c++17, -O2, -pedantic
具有正确的汇编器输出

第二个 (bool_from2) 在 gcc 上出错, 它还在 VS 中显示 Intellisense 错误,但编译没有错误。

我在 cppreference 或标准草案等中找不到任何内容表明符合代码需要 decltype(atype),但是...???

我的问题是需要 decltype。 我的编译器标志是否适用于 C++17 一致性检查。

代码:

#include <utility>

namespace ns {
volatile bool vb;

template<bool B> struct bool_ : std::bool_constant<B> {};

// using decltype(btype) in trailing return compiles in all 3
template<typename Bool> constexpr auto bool_from1(Bool btype)
-> bool_<decltype(btype)::value> {
    return bool_<btype.value>{};
}
void test1() {
    static_assert( // simple test
        bool_from1(std::true_type{}).value
        );
    vb = bool_from1(std::true_type{}).value; // check output
}

// without decltype in trailing return compile in VS and clang
// but errors out in gcc; and VS shows Intelisense errors but compiles
template<typename Bool>
constexpr auto bool_from2(Bool btype)
// ^ gcc 8.2 error: deduced class type 'bool_' in function return type
-> bool_<btype.value> {
    // ^ gcc: invalid template-id; use of paramter outside function body before '.'
    //^ VS Intellisense on btype: <error-constant>; a paramter is not allowed
    return bool_<btype.value>{};
}

void test2() {
    static_assert(
        bool_from2(std::true_type{}).value
        //^ gcc: bool_from1 was not declared in this scope
        );
    vb = bool_from2(std::true_type{}).value; // check output
}
}

最佳答案

这看起来像一个 gcc 错误和 bug report: "Trailing return types" with "non-type template arguments" which could be "constant expressions" produce a parsing error似乎适合这种情况:

Consider the following snippet:

template <int>
struct bar {};

template <class I>
auto foo(I i) -> bar<i()> { return {}; }

int main()
{
    foo([]{ return 1; }); // (0)
}

This compiles and works as intended on clang++5, but produces a compile-time error on g++7:

prog.cc:5:25: error: template argument 1 is invalid
auto foo(I i) -> bar<i()> { return {}; }

关于c++ - 使用参数类型的值在尾随返回中需要 decltype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53344692/

相关文章:

c++ - 为什么用户定义的字符串文字和整数文字有不同的行为?

c++ - 抛出失败信号的参数

c++ - 关于变量在内存中位置的问题

c++ - 拆分循环相关的CRTP类 header 时,函数调用不匹配

c++ - 调用另一个翻译单元中专门的功能模板

c++ - "Reading"POD 预增量结果不会产生未定义的行为。为什么呢?

c++ - 将多个数组转换为元组

javascript - 如何在vue模板中按行分割内联JS表达式?

c++ - 如何让编译器推断模板的返回类型?

c++ - 声明嵌套 namespace `std`是否合法?