首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“模仿”std::解密问题。在g++中工作(某种程度上),无法在clang++中编译

“模仿”std::解密问题。在g++中工作(某种程度上),无法在clang++中编译
EN

Stack Overflow用户
提问于 2015-06-16 00:09:38
回答 1查看 207关注 0票数 3

为了更好地理解std::解密,我想出了以下“玩具模型”代码:

代码语言:javascript
复制
#include <iostream>
#include <typeinfo>

struct Bar
{
    Bar(double);  // some non-default ctor
    double f();   // some function of which return type we want to get
};

using Barref = Bar&&; // emulating std::declval<Bar>()

int main()
{
    // FUNKY, compiles in g++, not in clang++
    // error: unexpected type name 'Barref': expected expression
    decltype(Barref.f()) x; // (1)
    std::cout << typeid(x).name() << std::endl; // i -> int INCORRECT

    // OK, just for testing
    decltype(std::declval<Bar>().f()) y; // (2)
    std::cout << typeid(y).name() << std::endl; // d -> double CORRECT
}

因此,我将类型为Barref作为Bar&&类型的rvalue引用,并在(1)中的decltype表达式中使用它。如果我正确理解,这正是std::declval所做的,它是一个非定义函数,它返回对其模板参数的rvalue引用。

代码语言:javascript
复制
template<class T>
typename std::add_rvalue_reference<T>::type declval();

因此,我们可以在未评估的上下文(如decltype )中使用后者。当类型有一个非默认的ctor时,它是有用的,并且我们希望获得一些关于某个成员函数的类型信息,而不需要构造对象。我认为下面的代码就是这么做的。g++5.1 编译它,但是xint类型的(而不是double,正如我所猜测的)。然而,clang++ 编译代码失败

错误:意外类型名称'Barref':预期表达式解密类型(barreg.f()) x;

我的问题:

  1. 上面的代码合法吗?我对decltype(Barref.f())的使用真的和使用decltype(std::declval<Bar>().f())一样吗?这似乎有点奇怪,因为Barref.f()实际上不是一个函数的返回值(即使没有计算)。我意识到,即使是decltype(Bar.f())也编译(g++),没有任何类型别名。
  2. 如果代码是合法的,为什么x的类型是int而不是double
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-16 00:31:43

减到

代码语言:javascript
复制
struct Meow {};

int main(){
    decltype(Meow.purr()) d;
}

这是明显无效的代码,但GCC 5.1和主干接受它。除了“臭虫”,没什么可说的。有趣的是,两者都正确地拒绝了

代码语言:javascript
复制
struct Meow {};
decltype(Meow.purr()) d;
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30856911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档