当前位置: 首页 > 知识库问答 >
问题:

在使用参数类型的值的尾部返回中是否需要decltype

胡昊
2023-03-14

在试图理解与c 17兼容的代码时,我被下面的代码搞糊涂了,其中函数在尾部返回类型中使用integral_constant类型参数的值。(请随时更正我的术语等,尝试学习)

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

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

第一个(bool_from1)在
MSVC 15.8上编译ok; /std: c 17, /O2, /permissive-
and clang8.7.0.0and gcc 8.2;-std=c 17,-O2,-迂腐
具有正确的汇编器输出

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

我在参考文件或标准草案等中找不到任何能向我表明一致性代码需要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
}
}

共有1个答案

太叔英锐
2023-03-14

这看起来像是一个gcc错误和错误报告:“Trailing return types”和“non-type template arguments”,可能是“常量表达式”,生成的解析错误似乎适合这种情况:

考虑以下片段:

template <int>
struct bar {};

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

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

这在clang 5上按预期进行编译和工作,但在g 7上产生编译时错误:

prog.cc:5:25: error: template argument 1 is invalid
auto foo(I i) -> bar<i()> { return {}; }
 类似资料:
  • 我在读一篇关于“新”C特性的文章时,遇到了decltype和它的用法。我理解decltype后面的原因,比如后面的返回类型 没有它,编译器将无法派生模板函数的返回类型。但是为什么语法是这样的呢? 为什么不使用 这会让人感觉更“自然”,因为返回类型是在正常情况下声明的,尽管这是两个参数的结果。这是因为它与其他东西冲突,还是因为如果语法是不值得的,它会给编译器带来额外的工作?

  • 我想使返回数据类型的的函数与传入的参数的数据类型相同。例如,我会这样调用函数: 因为我将一个传递给,所以它返回了一个

  • 问题内容: 在redux文档中给出的示例中,似乎总是从中间件返回一些东西。但是,当我打电话不返回时,一切似乎都正常。 在redux源中,它似乎正在调用每个中间件的返回值。 这使我相信,它为所有中间件运行后提供了一种可选的方式来运行调度。 有人可以确认我们是否必须始终从中间件返回值吗?为什么? 问题答案: 我实际上是前几天在这条推文上发表的。 默认情况下,该方法返回传递的操作。由于中间件管道环绕,因

  • 问题内容: 根据Java API规范,Collections.reverseOrder的签名为 方法说明中给出的示例说它需要用作 当我们调用该方法时,我们在任何地方都没有指定使用哪种类型(T解析为什么)。 在这种情况下,编译器如何解析T?可以根据分配给它的对象的类型来解析返回类型(T)吗? 顺便说一句,我知道重载的方法。 问题答案: Arrays.sort()知道它需要哪种比较器,因为它是由第一个

  • 尾部调用优化对返回void的函数的递归调用有效吗?例如,我有一个函数,void fun() 在这里,编译器不会知道,调用fun()是最后一条语句。那么尾部调用优化是否只针对返回某些值的函数?

  • 我试图创建一个返回泛型类型参数的方法。 我有一个类车辆订单扩展抽象类订单。在类订单中,我创建了一个抽象方法接收HiredObject。这个方法不会接收任何参数,并将返回一个泛型。 我在VehicleOrder类中实现了这个方法,并将其设置为返回类参数vehicle。 问题是,当我实例化一个新的VeilceOrderorororororororororororororderororororororo