gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:07:49 24 4
gpt4 key购买 nike

首先,我构建了四个结构,每个结构都返回值、左值引用、const 左值引用、右值引用。我在包装器(BC)中使用它们,在这些包装器的方法 func() 中,我想保留 Afunc() 的引用和 cv 限定符。

在 C++11 中,我使用了尾随返回类型。但随着 c++14 中正常返回类型推导的到来,我猜我可以跳过尾部,但只有 auto,返回类型像普通 一样忽略限定符和引用自动

然后,我的问题是在 c++14 中实现它的最佳方法是什么,它的行为就像下面的类 B 一样?当它很琐碎时,写尾部(通常是 decltype(return expression))有时会令人沮丧。

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 中编译没有问题。

最佳答案

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

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

A a;
};

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

将代码的最后部分更改为

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 造成的。)


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

If the placeholder is the decltype(auto) type-specifier, the declared type of the variable or return type of the function shall be the placeholder alone. The type deduced for the variable or return type is determined as described in 7.1.6.2, as though the initializer had been the operand of the decltype. [ Example:

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<int>
decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
auto *x7a = &i; // decltype(x7a) is int*
decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)

— end example ]

关于c++ - 如何在 c++1y 的返回类型推导中保留 cv 限定符或引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16827034/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com