首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在c++1y中保留返回类型推导中的cv限定符或引用?

如何在c++1y中保留返回类型推导中的cv限定符或引用?
EN

Stack Overflow用户
提问于 2013-05-30 10:33:00
回答 1查看 635关注 0票数 5

首先,我构造了四个结构,每个结构返回value,l-value引用,const l-value引用,r-value引用。我在包装器(BC)中使用它们,在这些包装器的方法func()中,我希望保留Afunc()的引用和cv限定符。

在c++11中,我使用了尾随返回类型。但是随着c++14中正常返回类型演绎的到来,我猜我可以跳过后面的部分,但只有在使用auto时,返回类型才会像普通的auto一样忽略限定符和引用。

那么,我的问题是,在行为类似于下面的B类的c++14中实现它的最佳方式是什么?有时编写尾部(通常是decltype(返回表达式))会让人沮丧,因为它是微不足道的。

代码语言:javascript
复制
struct A1 {
    int func(){
        return x;
    }
    int x{3};
};

struct A2 {
    int& func(){
        return x;
    }
    int x{3};
};

struct A3 {
    const int& func(){
        return x;
    }
    int x{3};
};

struct A4 {
    int&& func(){
        return std::move(x);
    }
    int x{3};
};

template <class A>
struct B{
    auto func() -> decltype(std::declval<A>().func())
    {
        return a.func();
    }

    A a;
};

template <class A>
struct C{
    auto func()
    {
        return a.func();
    }

    A a;
};

int main(){
    std::cout << std::boolalpha;

    B<A1> b1;   
    B<A2> b2;   
    B<A3> b3;   
    B<A4> b4;

    static_assert(std::is_same<decltype(b1.func()), int>::value, "true");
    static_assert(std::is_same<decltype(b2.func()), int&>::value, "true");
    static_assert(std::is_same<decltype(b3.func()), const int&>::value, "true");
    static_assert(std::is_same<decltype(b4.func()), int&&>::value, "true");

    C<A1> c1;   
    C<A2> c2;   
    C<A3> c3;   
    C<A4> c4;

    static_assert(std::is_same<decltype(c1.func()), int>::value, "true");
    static_assert(std::is_same<decltype(c2.func()), int>::value, "true");
    static_assert(std::is_same<decltype(c3.func()), int>::value, "true");
    static_assert(std::is_same<decltype(c4.func()), int>::value, "true");
}

请注意,此程序在带有-std=c++1y选项的gcc 4.8中编译时没有问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-30 10:44:34

C++14的提案包括一个( Jason Merrill的N3638),它定义了一个特殊的声明来实现这一点,使用decltype(auto)而不是auto

代码语言:javascript
复制
template <class A>
struct C{
  decltype(auto) func()
    {
        return a.func();
    }

    A a;
};

GCC在4.9 snapshot中实现了这一点,请参阅C++部分。

在将代码的最后部分更改为

代码语言:javascript
复制
static_assert(std::is_same<decltype(c1.func()), int>::value, "true");
static_assert(std::is_same<decltype(c2.func()), int&>::value, "true");
static_assert(std::is_same<decltype(c3.func()), const int&>::value, "true");
static_assert(std::is_same<decltype(c4.func()), int&&>::value, "true");

GCC 4.9版快照对其进行了编译,而4.8版则没有。

(注意:如果在编译时使用-g选项,两个编译器都会在内部编译器错误时崩溃。这要归功于Bug 56014。)

为了完整起见,以下是提案中最相关的部分:

如果占位符是decltype(自动)类型说明符,则变量的声明类型或函数的返回类型应仅为占位符。为变量或返回类型推导的类型按照7.1.6.2中所述确定,就像初始化器是decltype的操作数一样。示例:

int i;int&& f();auto x3a = i;// decltype(x3a) is int decltype( auto ) x3d = i;// decltype(x3d) is int auto x4a = (i);// decltype(x4a) is int decltype(auto) x4d = (i);// decltype(x4d) is int& auto x5a = f();// decltype(x5a) is int decltype(auto) x5d = f();// decltype(x5d) is int&& auto x6a ={ 1,2 };// decltype(x6a) is std::initializer_list decltype( auto ) x6d ={ 1,2 };//错误,{ 1,2}不是表达式auto *x7a = &i;// decltype(x7a) is int* decltype(auto)*x7d = &i;//错误,声明类型不是普通的decltype(auto)

-结束示例

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16827034

复制
相关文章

相似问题

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