指向引用的指针获取器
Posted
技术标签:
【中文标题】指向引用的指针获取器【英文标题】:Pointer getter to a reference 【发布时间】:2017-04-01 14:16:17 【问题描述】:我有一个带有引用的类,并且想要一个返回指针的 getter。
class X
std::string& text;
public:
auto GetText() -> decltype(text) * return &text); // doesn't work
X(std::string& text): text(text)
;
简单的方法是将指针传递给这个类。但是如果我传递一个引用,我可以得到一个带有 getter 的指针吗?
编辑:这是错误信息
error: cannot declare pointer to 'std::__cxx11::string& aka class std::__cxx11::basic_string<char>&'
auto GetText() -> decltype(text) * return &text);
^
【问题讨论】:
“不起作用”不是一个有用的问题描述。你有编译错误吗?如果是这样,请将它们放在您的问题中。 为什么不直接做std::string* GetText() return &text;
?您的代码也有拼写错误(当然您的意思是
而不是 )
来关闭该功能)。 `
这一切似乎完全没有必要。
当您从字面上理解“始终自动”的闲置饮水机时会发生这种情况,并且完全没有任何反思地运行它。
strip the reference 可以,但为什么要这样做?正如 Kerrek 所说,这一切似乎完全没有必要。
【参考方案1】:
首先,
auto GetText() -> decltype(text) * return &text); // doesn't work
是声明此签名的一种非常可恶的方式。喜欢
std::string* GetText() return &text);
甚至只是
auto GetText() return &text);
但这不是代码审查。
这里的问题是你要求一个指向text
成员变量的声明类型的指针,它是一个字符串引用(std::string&
)。从评论部分,您似乎没有意识到 decltype
尊重其论点的“引用”、“常量”和“易失”。
在 C++ 中不能有指向引用的指针,例如std::string&*
格式错误。致电std::remove_reference_t 应该可以解决该问题,例如
auto GetText() -> std::remove_reference_t<decltype(text)> * return &text);
但是,在这种情况下,auto
无论如何都会正确推断出您的类型,因此您的显式声明是不必要的。
【讨论】:
令人着迷!谢谢大家。【参考方案2】:我为我最初的问题创建了一个test program。该程序有一个带有指针和返回引用的 getter 的类,以及带有引用和返回指针的 getter 的第二个类。
而且似乎-> std::remove_reference_t<decltype(text)>
可以替换为-> decltype(&text)
。
欢迎评论。
// g++ main.cpp -o test_reference_pointer && strip -s test_reference_pointer && ./test_reference_pointer
#include <iostream>
// A class with a pointer and a getter that returns a reference.
class A
std::string *text;
public:
std::string& GetText_old_way() return *text;
auto GetText_pure_auto() return *text;
auto GetText_pointer_arithmetic() -> decltype(*text) & return *text;
public:
A(std::string *text): text(text)
;
// A class with a reference and a getter that returns a pointer.
class B
std::string& text;
public:
std::string *GetText_old_way() return &text;
auto GetText_pure_auto() return &text;
auto GetText_pointer_arithmetic() -> decltype(&text) return &text;
auto GetText_remove_reference() -> std::remove_reference_t<decltype(text)> * return &text;
public:
B(std::string& text): text(text)
;
int main()
std::string text = "hello, world";
//TEST
A a(&text);
unsigned int i0;
std::cout << "-- Test 1:"<< std::endl;
++i; std::cout << i << ". " << a.GetText_old_way() << std::endl;
++i; std::cout << i << ". " << a.GetText_pointer_arithmetic() << std::endl;
++i; std::cout << i << ". " << a.GetText_pure_auto() << std::endl;
std::cout << std::endl;
//TEST
B b(text);
unsigned int i0;
std::cout << "-- Test 2:"<< std::endl;
++i; std::cout << i << ". " << *b.GetText_old_way() << std::endl;
++i; std::cout << i << ". " << *b.GetText_pointer_arithmetic() << std::endl;
++i; std::cout << i << ". " << *b.GetText_remove_reference() << std::endl;
++i; std::cout << i << ". " << *b.GetText_pure_auto() << std::endl;
std::cout << std::endl;
return 0;
【讨论】:
注意A
、GetText_pure_auto
类中的注释正在返回底层字符串的副本而不是引用,这可能不是一个好主意。
在A
类中,在auto GetText_pointer_arithmetic
中,decltype(*text)&
的尾随&
是不必要的; decltype(*text)
是等价的。此外,如果您使用的是 C++14,则此签名可以更紧凑地编写为 decltype(*text) GetText_pointer_arithmetic()
或 decltype(auto)
或 auto&
"而且似乎 -> std::remove_reference_tstd::remove_reference_t<decltype(text)>*
可以替换为 decltype(&text)
,而不是 std::remove_reference_t<decltype(text)>
auto GetText_pointer_arithmetic() -> decltype(*text) return *text;
与auto GetText_pointer_arithmetic() -> decltype(*text) & return *text;
相同?第一个看起来返回一个std::string
而不是std::string&
。
你明白当你取消引用一个指针时,结果类型是一个引用,对吗?以上是关于指向引用的指针获取器的主要内容,如果未能解决你的问题,请参考以下文章
解引用指针并存储对指向数据的引用,然后获取引用地址并对其执行指针运算。 C++