使用auto和decltype从模板类中的函数返回引用
如何强制模板类中的函数使用auto / decltype返回对成员变量的引用?
这是我想要做的一个简单的例子。 假设你有一个模板类,它将一些东西存储在私有成员变量a_
,如下所示:
#include <iostream>
template <typename T>
class A
{
private:
T a_;
public:
A(T a) : a_(a) {}
// 1. Return const reference to a_
const T & get() const { return a_; }
// 2. Return non-const reference to a_
T & get() { return a_; }
};
int main(int argc, char *argv[])
{
A<int> a(3);
const auto & a1 = a.get(); // 1. Return const reference to a_
//a1 = 4; // Shouldn't compile
std::cout << "Value of a = " << a.get() << std::endl;
auto & a2 = a.get(); // 2. Return non-const reference to a_
a2 = 5;
std::cout << "Value of a = " << a.get() << std::endl;
return 0;
}
预期/期望的输出是:
Value of a = 3
Value of a = 5
但是现在,假设我希望编译器推导出A<T>
const和non-const get()
函数返回的类型,并且我希望确保这两个调用都返回对a_
引用 。
我最好的猜测是目前:
template <typename T>
class A
{
private:
T a_;
public:
A(T a) : a_(a) {}
// 1. Return const reference to a_
const auto get() const -> std::add_lvalue_reference<const decltype(a_)>::type
{
return a_;
}
// 2. Return non-const reference to a_
auto get() -> std::add_lvalue_reference<decltype(a_)>::type
{
return a_;
}
};
但是没有编译。 GCC给出的第一个错误是:
decltype.cpp:11:29: error: expected type-specifier
decltype.cpp:11:26: error: expected ‘;’ at end of member declaration
decltype.cpp:11:29: error: ‘add_lvalue_reference’ in namespace ‘std’ does not name a type
其动机在于我的蒸馏示例代码,但是源于尝试减少模板参数的数量,当一个(或多个)这些参数仅用于指定编译器应该(我认为)的返回类型时,能够自行推断。 注意:在现实世界中, get()
的返回类型不是a_
的返回类型,而是某些函数f(a_)
的返回类型,我知道它可以被编译器推理。 因此我在这个例子中需要auto / decltype。
让我感到困惑的是,编译器可以在非模板类中使用几乎相同的代码正确地推导返回类型:
class A
{
private:
int a_;
public:
A(int a) : a_(a) {}
// 1. Return const reference to a_
const auto get() const -> std::add_lvalue_reference<const decltype(a_)>::type
{
return a_;
}
// 2. Return non-const reference to a_
auto get() -> std::add_lvalue_reference<decltype(a_)>::type
{
return a_;
}
};
任何帮助了解我失踪将不胜感激。
细节:
Centos 6.5
gcc (GCC) 4.7.2 20121015 (Red Hat 4.7.2-5)
只要提到它,你实际上不必使用std::add_lvalue_reference
来获得你想要的行为。 这在我的书中同样适用,并且更具可读性。
template <typename T>
class A {
private:
T a_;
public:
A(T a) : a_(a) {}
const auto get() const -> const decltype(a_) & {
return a_;
}
auto get() -> decltype(a_) & {
return a_;
}
};
int main() {
A<int> a(1);
cout << a.get() << endl;
a.get() = 2;
cout << a.get() << endl;
}
总结a_
在尾随返回类型一对额外的括号来获得表达的类型a_
而不是声明的类型变量的a_
(住在Coliru):
// 1. Return const reference to a_
auto get() const -> decltype((a_))
{
return a_;
}
// 2. Return non-const reference to a_
auto get() -> decltype((a_))
{
return a_;
}
或者如果C ++ 1y可用:
// 1. Return const reference to a_
auto& get() const
{
return a_;
}
// 2. Return non-const reference to a_
auto& get()
{
return a_;
}
链接地址: http://www.djcxy.com/p/66503.html
上一篇: Using auto and decltype to return reference from function in templated class
下一篇: Specialize function template with decltype trailing return type