2013-11-28 3 views
2

У меня есть теоретический вопрос о шаблонах в C++.
Скажем, у меня есть следующий код:C++ template point to member

Code

struct C{ 
    int val = 15; 
}; 

struct B{ 
    C c; 
    int k = 9; 
}; 

struct A{ 
    template<typename T, typename FType, FType T::* Field = nullptr> 
    void test(T& d){ 
     if (Field != nullptr){ 
      int a = d.*Field; 
     } 
    } 
}; 


int main(int argc, char *argv[]) 
{ 

    A a; 
    B be; 

    a.test<B, int, &B::c::val>(be); 
    //a.test<B, int, &B::k>(be); 
} 

Вопрос: почему я не могу получить доступ к B :: C :: вали поля, когда я могу получить доступ B :: k?
B :: c :: val также является членом B. Или нет?

+0

int val = 15; это неправильно внутри structre ... использовать конструкторы, чтобы иметь начальное значение. – Nik

+0

Нет такой вещи, как 'B :: c :: val'. У вас может быть только класс или имя пространства имен слева от '::'. 'B :: c' не является ни тем, ни другим. Это не имеет никакого отношения к шаблонам. –

+1

это будет работать «a.test (be.c)» – Nik

ответ

1

B::c является членом B и C::val является членом C, но нет ничего, как B::c::val

Что вы хотели сделать здесь может быть достигнуто, как это:

struct A { 
    template<typename T, typename OType, typename IType, OType T::* OField = nullptr, IType OType::* IField = nullptr> 
    void test(T& d){ 
    if (OField != nullptr && IField != nullptr) { 
     auto a = d.*OField.*IField; 
    } 
    } 
}; 

int main(int argc, char *argv[]) 
{ 

    A a; 
    B be; 

    a.test<B, C, int, &B::c, &C::val>(be); 
} 

http://coliru.stacked-crooked.com/a/f89b96274218e223

Конечно, вы могли бы указать указатели на элементы в качестве параметров функции и позволить компилятору вывести параметр paramete rs для вас.