[英]How to use friend to access STL private member
When I do this... 当我这样做时...
auto t = typeid(float);
... I get: ...我得到:
Error C2248 'type_info::type_info': cannot access private member declared in class 'type_info' 错误C2248'type_info :: type_info':无法访问在类'type_info'中声明的私有成员
Of course, I know I can do this... 当然,我知道我可以做到...
auto t = typeid(float).name();
But if I wanted to use the first expression, how would I go about tampering with the type_info class and using friend to achieve my objective? 但是,如果我想使用第一个表达式,我该如何篡改type_info类并使用friend来实现我的目标? Any suggestions?
有什么建议么?
You can't make your class a friend
of a standard class. 您不能让您的班级成为标准班级的
friend
。
A typeid
expression is an lvalue, so you can simply bind a reference to it: 一个
typeid
表达式是一个左值,因此您可以简单地将引用绑定到它:
auto& t = typeid(float);
The reason you cannot do this is the copy constructor and the assignment operator of std::type_info
are marked as delete
per [type.info]. 您无法执行此操作的原因是复制构造函数,并且
std::type_info
的赋值运算符被标记为每个[type.info]的delete
。 So 所以
auto t = typeid(float);
Will attempt to call the copy constructor which will fail. 将尝试调用将失败的复制构造函数。
As TartanLlama points out in his answer you can capture a reference to it with 正如TartanLlama在他的回答中指出的那样,您可以使用
auto& t = typeid(float);
Error C2248 'type_info::type_info': cannot access private member declared in class 'type_info'
This error message refers to the copy constructor of type_info
which you've tried to invoke with auto t = typeid(float);
此错误消息引用了您尝试使用
auto t = typeid(float);
调用的type_info
的副本构造函数auto t = typeid(float);
. 。
But if I wanted to use the first expression, how would I go about tampering with the
type_info
class and using friend to achieve my objective?但是,如果我想使用第一个表达式,我该如何篡改
type_info
类并使用friend来实现我的目标? Any suggestions?有什么建议么?
Even if you could manipulate type_info
's definition, which you cannot , what would you possibly do? 即使您可以操纵
type_info
的定义(您也无法做到),您可能会怎么做? The copy constructor is not private because it needs to be hidden from you but because the language does not define what it means to copy a type_info
. 复制构造函数不是私有的,因为它需要向您隐藏,但因为该语言未定义复制
type_info
含义。 In fact, even if you somehow declared the member function as public
(which is already purely hypothetical), there would be no definition and thus a linker error. 实际上,即使您以某种方式将成员函数声明为
public
函数(这已经纯粹是假设的),也没有定义,因此也就没有链接器错误。
I don't know why GCC is not more specific in its error message here. 我不知道为什么GCC在这里的错误消息中没有更具体。 With C++11, the copy constructor is not just
private
but deleted and that's the reason it cannot be used. 使用C ++ 11时,复制构造函数不仅是
private
而且已删除 ,这就是不能使用它的原因。 Coincidentally, MSVC's error message is more appropriate, as it says: 碰巧的是,MSVC的错误消息更合适,因为它说:
error C2280: 'type_info::type_info(const type_info &)' :
attempting to reference a deleted function
A modern C++11 solution to your problem is to use std::type_index
, which is a copyable wrapper around std::type_info
. 解决问题的现代C ++ 11解决方案是使用
std::type_index
,它是std::type_info
周围的可复制包装器。 Here is an example: 这是一个例子:
#include <typeindex>
int main()
{
auto t = std::type_index(typeid(float));
}
Class std::type_info
has deleted copy constructor. 类
std::type_info
已删除副本构造函数。
type_info(const type_info& rhs) = delete; // cannot be copied
^^^^^^^^
On the other hand (5.2.8 Type identification) 另一方面(5.2.8类型识别)
1 The result of a typeid expression is an lvalue of static type const std::type_info (18.7.1) and dynamic type const std::type_info or const name where name is an implementation-defined class publicly derived from std :: type_info which preserves the behavior described in 18.7.1.69 The lifetime of the object referred to by the lvalue extends to the end of the program . 1 typeid表达式的结果是静态类型const std :: type_info(18.7.1)和动态类型const std :: type_info或const name 的左值 ,其中name是从std :: type_info公开派生的实现定义的类,保留18.7.1.69中描述的行为。lvalue 引用的对象的生存期延长到程序的结尾 。 Whether or not the destructor is called for the std::type_info object at the end of the program is unspecified.
程序末尾是否为std :: type_info对象调用析构函数是不确定的。
So you can write for example 所以你可以写例如
#include <iostream>
int main()
{
decltype( auto ) t = typeid( float );
std::cout << t.name() << std::endl;
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.