指向成员的指针转换为指向成员基类的成员的指针 [英] pointer to member conversion to a pointer to member that is a member's base class

查看:81
本文介绍了指向成员的指针转换为指向成员基类的成员的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的,


坚果壳中存在问题(参见下面的程序):


可以将指针转换为F< T>指向I的指针。

现在如果我有指向成员的指针F< T>实体:: *"我可以将它转换为我

实体:: *吗?

编译器不允许我这样做(我已经尝试过VC 7.1和Comeau 4.3.3)。

如果我做reinterpret_cast那么程序将被编译并运行为

预期尽管我想知道这个可能的含义

方法。


这里的目标是为类创建一个静态字段数组,并且能够在这个数组上执行算法(b
)就像主要功能中的for循环一样。)


谢谢,

弗拉基米尔。


#include< string>


使用命名空间std;


struct I

{

虚拟char const * foo()= 0;

};


模板< typename T>

struct F:public I

{

char const * foo()

{

返回typeid(T).name();

}


T v _;

};


struct entity

{

typedef I entity :: * mem_t;


静态mem_t字段[4];


F< int> f1_;

F< char> f2_;

F< string> f3_;

F< double> f4_;

};


entity :: mem_t entity :: fields [4] = {

reinterpret_cast< mem_t>( & entity :: f1_),

reinterpret_cast< mem_t>(& entity :: f2_),

reinterpret_cast< mem_t>(& entity :: f3_),

reinterpret_cast< mem_t>(& entity :: f4_),

};

int main(int,char **)

{

实体e;

for(int i = 0; i< 4; ++ i)

{

printf("%s \ n",(e。*(entity :: fields [i]))。foo());

}


返回0;

}

解决方案

Vladimir_petter写道:

坚果壳中存在问题(参见下面的程序):

将指针转换为F< T>是可以的。指向I.


是的,我是F< T>的明确且可访问的基类。

现在,如果我有指向成员的指针 ; F< T>实体:: *"我可以将其转换为I
entity :: *吗?


不含蓄,不。

编译器不允许我这样做(我已经尝试过VC 7.1和Comeau 4.3.3)。


那是对的。在当前的标准中没有这样的转换。

如果我做reinterpret_cast那么程序将被编译并运行为
期望尽管我想知道这个可能的含义
做法。


由于现在定义了语言,你的程序会导致未定义的行为。

它甚至可能按预期工作(显然它确实如此)。但它可能不会是b $ b或它可能会做一些非常糟糕的事情,比如格式化你的硬盘。


如果我是你,我会陈述我的情况到comp.std.c ++并要求语言添加

:指向类型D的T成员的指针应该是

可转换为指向成员的指针如果B是明确的B / B $ B和B的可访问基数,则为B类型的T。它是4.10 / 3的逻辑扩展。


在C ++术语中: {D cv T :: *}应该可以转换为{B cv T :: *}和

{D cv T ::&}应该可以转换为{B cv T ::&} }(其中

是隐含的,因为所有指针转换都适用于引用

,但没有空引用除外)

这里的目标为类创建一个静态字段数组,并能够在此数组上执行算法(如主函数中的for循环)。


听起来不错。

谢谢,
弗拉基米尔。

#include< string>

using namespace std;

struct I
{
虚拟字符const * foo()= 0;
};

template< typename T>
struct F:public I
{char const * foo()
{
返回typeid(T).name(); <结构实体
{
typedef I entity :: * mem_t;

静态mem_t字段[4];

F< int> f1_;
F< char> f2_;
F< string> f3_;
F< double> f4_;
};

entity :: mem_t entity :: fields [4] = {
reinterpret_cast< mem_t>(& entity :: f1_),
reinterpret_cast< mem_t>(& entity :: f2_),
reinterpret_cast< mem_t>(& entity :: f3_),
reinterpret_cast< mem_t>(& entity :: f4 _),};

int main(int,char **)
{
实体e;
for(int i = 0; i< 4; ++ i )
{
printf("%s \ n",(e。*(entity :: fields [i]))。foo());
}

返回0;
}




Victor


Hello Viktor ,


我对你的回复表示赞同。

编译器不允许我这样做(我''我试过VC 7.1和Comeau
4.3.3)。
这是对的。在当前的标准中没有这样的转换。




你能指点我标准中的一个段落,它会明确说明这个吗?

我在查看4.11,5.2.9 / 9,5.3.1 / 2,1.3 / 3。其中没有一个明确

声明

这是无效的。

如果我做reinterpret_cast然后程序将被编译并运行为
期望尽管我想知道这种方法的可能含义。



由于现在定义了语言,你的程序导致未定义的行为。
它甚至可能按预期工作(显然它确实如此)。但它可能不会或者它可能会做一些非常糟糕的事情,比如格式化你的硬盘。

如果我是你,我会把我的案例提交给comp.std.c ++并询问对于语言的补充:如果B是明确的,则可以将指向D类型的T成员的指针转换为指向B类型成员的指针
D.它的基础是4.10 / 3的逻辑扩展。




我想我会这样做。不幸的是,解决我当前的问题无济于事:-(

用C ++术语:{D cv T :: *}应该可以转换为{B cv T :: *}和
{D cv T ::&}应该可以转换为{B cv T ::&}(因为所有指针转换都适用于引用,所以这是隐含的。
>除了没有空引用之外)


我同意你上面说过的事情,除了我认为没有这样的事情。 />
a对成员的引用(见8.3.2 / 3)。

这里的目标是为类创建一个静态字段数组并且能够在这个数组上执行算法(比如主要的
函数中的for循环)。



听起来不错。




但尚未到达:-(。


谢谢,

弗拉基米尔。


" Vladimir_petter"< vl ***** @ hotmail.com>写道...... Hello Viktor,

我对你的回复很感兴趣。

编译器不让我做(我已经尝试过VC 7.1和Comeau
4.3.3)。
这是对的。在当前的标准中没有这样的转换。



你能指点我标准中的一个段落,清楚地说明这个吗?




我怎样才能指出你不存在的段落?看完整个

第4条,如果你找不到它,它就不存在了。第4条包含_all_

转换。

我在查看4.11,5.2.9 / 9,5.3.1 / 2,8.3 / 3。他们都没有明确表示
这是无效的。


标准以特殊的方式组织。如果某些事情不明确允许,则禁止使用。这包括转换。如果

没有5.2.10中明确允许的操作,即使使用reinterpret_cast也不允许使用

如果我做了reinterpret_cast,那么程序将被编译并运行为
期望尽管我想知道这种方法的可能影响。
作为现在定义了语言,你的程序会导致未定义的行为。
它甚至可能按预期工作(显然它确实如此)。但它可能
不是

或者它可能会做一些非常糟糕的事情,比如格式化你的硬盘。

如果我是你,我将把我的案例提交给comp.std.c ++,并要求对该语言添加
:指向D类型成员的指针应该可以转换为指向成员的指针如果B是
明确且可访问的D基础,那么B类型为T.它是4.10 / 3的逻辑扩展。



我认为我会做那。不幸的是,它无助于解决我当前的问题: - (。




否,但它可能会确保在其他地方将其移植到其他地方时

你将有一个可行的解决方案。同时享受你的reinterpret_cast

解决方案,当它正常工作时。


在C ++术语中:{D cv T :: *}应该可以转换为{B cv T :: *}并且
{D cv T ::&}应该可以转换为{B cv T ::&} }(暗示因为所有指针转换都适用于引用
,但没有空引用除外)
我同意你上面说过的,除了我认为没有



这样的想法是对成员的引用(见8.3.2 / 3)。




嗯好的,但也许应该有。:-)

这里的目标是为一个类创建一个静态的字段数组,并且是
能够在这个数组上执行算法(比如主要的
函数中的for循环)。



听起来不错。



但是无法访问: - (。




我不确定我理解。你没有在原帖中说明

您的代码是否按照您的意愿运行?


V


Dear All,

There is the problem in nutshells (see the program bellow):

It is ok to convert pointer to F<T> to the pointer to I.
Now if I have pointer to member "F<T> entity::*" can I convert it to the "I
entity::*"?
Compiler does not let me to do that (I''ve tried on VC 7.1 and Comeau 4.3.3).
If I do reinterpret_cast then the program will be compiled and runs as
expected all though I would like to know possible implications of this
approach.

The goal here to create a static array of fields for a class and be able to
execute algorithms on this array (like the for loop in the main function).

Thanks,
Vladimir.

#include <string>

using namespace std;

struct I
{
virtual char const * foo()=0;
};

template <typename T>
struct F : public I
{
char const * foo()
{
return typeid(T).name();
}

T v_;
};

struct entity
{
typedef I entity::* mem_t;

static mem_t fields[4];

F<int> f1_;
F<char> f2_;
F<string> f3_;
F<double> f4_;
};

entity::mem_t entity::fields[4] = {
reinterpret_cast<mem_t>(&entity::f1_),
reinterpret_cast<mem_t>(&entity::f2_),
reinterpret_cast<mem_t>(&entity::f3_),
reinterpret_cast<mem_t>(&entity::f4_),
};
int main(int, char **)
{
entity e;
for(int i=0; i<4; ++i)
{
printf("%s\n", (e.*(entity::fields[i])).foo());
}

return 0;
}

解决方案

Vladimir_petter wrote:

There is the problem in nutshells (see the program bellow):

It is ok to convert pointer to F<T> to the pointer to I.
Yes, I is an unambiguous and accessible base class to F<T>.
Now if I have pointer to member "F<T> entity::*" can I convert it to the "I
entity::*"?
Not implicitly, no.
Compiler does not let me to do that (I''ve tried on VC 7.1 and Comeau 4.3.3).
That''s right. In the current Standard no such conversion exist.
If I do reinterpret_cast then the program will be compiled and runs as
expected all though I would like to know possible implications of this
approach.
As the language is defined now, your program causes undefined behaviour.
It might even work as expected (and apparently it does). But it might not
or it might do something really bad, like format your hard drive.

If I were you, I''d present my case to comp.std.c++ and asked for the
addition to the language: a pointer to a member of T of type D should be
convertible to a pointer to a member of T of type B if B is an unambiguous
and accessible base of D. It is a logical extension to 4.10/3.

In C++ terms: {D cv T::*} should be convertible to {B cv T::*} and
{D cv T::&} should be convertible to {B cv T::&} (which
is implied because all pointer conversions are applicable to references
with the exception that there are no null references)
The goal here to create a static array of fields for a class and be able to
execute algorithms on this array (like the for loop in the main function).
Sounds good.

Thanks,
Vladimir.

#include <string>

using namespace std;

struct I
{
virtual char const * foo()=0;
};

template <typename T>
struct F : public I
{
char const * foo()
{
return typeid(T).name();
}

T v_;
};

struct entity
{
typedef I entity::* mem_t;

static mem_t fields[4];

F<int> f1_;
F<char> f2_;
F<string> f3_;
F<double> f4_;
};

entity::mem_t entity::fields[4] = {
reinterpret_cast<mem_t>(&entity::f1_),
reinterpret_cast<mem_t>(&entity::f2_),
reinterpret_cast<mem_t>(&entity::f3_),
reinterpret_cast<mem_t>(&entity::f4_),
};
int main(int, char **)
{
entity e;
for(int i=0; i<4; ++i)
{
printf("%s\n", (e.*(entity::fields[i])).foo());
}

return 0;
}



Victor


Hello Viktor,

I apriciate your response.

Compiler does not let me to do that (I''ve tried on VC 7.1 and Comeau
4.3.3).
That''s right. In the current Standard no such conversion exist.



Could you point me to a paragraph in the standard that would clearly state
this?
I was looking in the 4.11, 5.2.9/9, 5.3.1/2, 8.3/3. None of them clearly
states that
this is invalid.

If I do reinterpret_cast then the program will be compiled and runs as
expected all though I would like to know possible implications of this
approach.



As the language is defined now, your program causes undefined behaviour.
It might even work as expected (and apparently it does). But it might not
or it might do something really bad, like format your hard drive.

If I were you, I''d present my case to comp.std.c++ and asked for the
addition to the language: a pointer to a member of T of type D should be
convertible to a pointer to a member of T of type B if B is an unambiguous
and accessible base of D. It is a logical extension to 4.10/3.



Well I think I''ll do that. Unfortunately it would not help to solve my
current problem :-(.

In C++ terms: {D cv T::*} should be convertible to {B cv T::*} and
{D cv T::&} should be convertible to {B cv T::&} (which
is implied because all pointer conversions are applicable to references
with the exception that there are no null references)
I agree with everithing you said above except that I think there is no such
a think as
a reference to a member (see 8.3.2/3).

The goal here to create a static array of fields for a class and be able
to execute algorithms on this array (like the for loop in the main
function).



Sounds good.



But yet unreachable :-(.

Thanks,
Vladimir.


"Vladimir_petter" <vl*****@hotmail.com> wrote...

Hello Viktor,

I apriciate your response.

Compiler does not let me to do that (I''ve tried on VC 7.1 and Comeau
4.3.3).
That''s right. In the current Standard no such conversion exist.



Could you point me to a paragraph in the standard that would clearly state
this?



How can I point you to the paragraph that doesn''t exist? See the entire
Clause 4, if you can''t find it, it doesn''t exist. Clause 4 contains _all_
conversions there are.
I was looking in the 4.11, 5.2.9/9, 5.3.1/2, 8.3/3. None of them clearly
states that
this is invalid.
The Standard is organized in a peculiar way. If certain things are not
explicitly allowed, they are prohibited. That includes conversions. If
there is no operation that is explicitly allowed in 5.2.10, it is not
allowed even with a reinterpret_cast.

If I do reinterpret_cast then the program will be compiled and runs as
expected all though I would like to know possible implications of this
approach.
As the language is defined now, your program causes undefined behaviour.
It might even work as expected (and apparently it does). But it might not

or it might do something really bad, like format your hard drive.

If I were you, I''d present my case to comp.std.c++ and asked for the
addition to the language: a pointer to a member of T of type D should be
convertible to a pointer to a member of T of type B if B is an unambiguous and accessible base of D. It is a logical extension to 4.10/3.



Well I think I''ll do that. Unfortunately it would not help to solve my
current problem :-(.



No, but it probably will ensure that when time comes to port it elsewhere
you will have a working solution. Meanwhile enjoy your reinterpret_cast
solution while it "works".


In C++ terms: {D cv T::*} should be convertible to {B cv T::*} and
{D cv T::&} should be convertible to {B cv T::&} (which
is implied because all pointer conversions are applicable to references
with the exception that there are no null references)
I agree with everithing you said above except that I think there is no


such a think as
a reference to a member (see 8.3.2/3).



Well, OK, but perhaps there should be. :-)

The goal here to create a static array of fields for a class and be able to execute algorithms on this array (like the for loop in the main
function).



Sounds good.



But yet unreachable :-(.



I am not sure I understand. Didn''t you indicate in your original post
that your code works as you want it?

V


这篇关于指向成员的指针转换为指向成员基类的成员的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆