How to write a C++ conversion operator returning r

2019-03-26 05:29发布

问题:

In C++ one can add implicit-conversion operators in a class or struct. For instance, 3D vector types usually include something like:

struct Vector {
    float x, y, z;
    operator float * () { return reinterpret_cast<float *>(this); }
};

to allow accessing the vector's elements with subscripts, passing to functions that want a pointer, etc. It occurred to me to wonder: can we instead write a conversion operator that returns a reference to array of float, instead of a pointer to float?

(This is of purely academic interest. I don't know what benefits a reference-to-array would have, if any, over a simple pointer.)

As a free function we can do this like:

float (&convert(Vector & v))[3]
{
    return reinterpret_cast<float(&)[3]>(v);
}

Vector v;
convert(v);

However, I haven't been able to find the right syntax to do this as a conversion operator. I've tried things like:

operator float(&)[3] ()
operator float(&())[3]
float (&operator())[3]

and various other permutations, but I just get various syntax errors (g++ 4.8.1).

Is it possible to write a conversion operator returning a reference to array, and if so, what is the syntax to do so?

回答1:

In fact you can, you almost had it with the last one:

(&operator float())[3];

As for the question of whether or not a typedef is ever necessary, I think it is from reading the comments on https://stackoverflow.com/a/6755760/2925619 (which answer is what helped me get the syntax for the above as well).

Edit:

Apparently, this syntax is incorrect and returning a reference to an array is forbidden as chris discovered for us. I guess you'll just have to settle for a typedef.



回答2:

If you are using C++11, the problem may be resolved by introducing the ref/ptr template aliases as defined below:

template<typename T>
using ref = T&;

template<typename T>
using ptr = T*;

With this aliases the declaration of reference to array conversion operator will be in form:

operator ref<float[3]>(); 

Also it make function taking/returning pointer to function/array declaration much cleaner, e.g.:

ptr<int()> foo(ptr<int(int)> bar);

Instead of:

int (*foo(int(*bar)(int)))();