2015-12-01 2 views
1

Рассмотрим следующий пример:Как бросить указатель на член базового класса в указатель на тот же член производного класса

struct foo { 
    int bax; 
}; 

struct fuu : foo { 
}; 

template<int foo::*> 
struct tox {}; 

template<int fuu::*> 
struct tux {}; 

int foo::* xo = &foo::bax; 
int fuu::* xu = &fuu::bax; // works 

typedef int foo::*boz; 

typedef tox<&foo::bax> qox; 
typedef tux<&fuu::bax> qux; // fails: 'int foo::*' cannot be converted to a value of type 'int fuu::*' 
typedef tux<(boz)&fuu::bax> qux; // fails: non-type template argument of type 'boz' (aka 'int foo::*') cannot be converted to a value of type 'int fuu::*' 

Этот пример также доступен на http://coliru.stacked-crooked.com/a/15f3e7acd8de04a3, Both лязг ++ и г ++ производить то же самое ошибка.

Как нарисовать fuu :: bax, так что оно принимается шаблоном tux?

ответ

3

К сожалению, я не думаю, что есть какой-либо способ сделать это. Об этой проблеме есть open defect report. Вам придется как-то обойти это, например, изменить tux, вместо этого он принимает int foo::* или добавляет еще один параметр шаблона:

template <typename T, int T::* arg> 
struct tux { 
    static_assert(std::is_convertible<int T::*, int fuu::*>::value, 
        "T must be an unambiguous accessible base of fuu"); 
    // note that this still works 
    // however, you won't be able to use it as a template argument 
    static constexpr int fuu::* pm = arg; 
}; 
Смежные вопросы