2015-08-30 34 views
5

jestem obecnie zatrzymany na błąd kompilacji, która tak naprawdę nie można zidentyfikować ...błąd podczas wywoływania funkcji członka integralna szablon z g ++ i szczęk ++

Oto minimalne przykład roboczych:

#include <iostream> 

template <typename T, int R> 
class a_type 
{ 
public: 
    template <int N> 
    double segment() 
     { 
      return 42; 
     } 
}; 

template <int M> 
double func() 
{ 
    a_type<double, M> a; 
    return a.segment<1>(); 
} 

int main(int argc, char *argv[]) 
{ 
    std::cout << func<10>() << std::endl; 
    return 0; 
} 

komunikat o błędzie z GCC brzmi:

g++ main.cpp -o main 
main.cpp: In function 'double func()': 
main.cpp:18:26: error: expected primary-expression before ')' token 
     return a.segment<1>(); 
         ^
main.cpp: In instantiation of 'double func() [with int M = 10]': 
main.cpp:23:28: required from here 
main.cpp:18:22: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<' 
     return a.segment<1>(); 
       ^

Clang mówi też coś podobnego:

clang++ main.cpp -o main 
main.cpp:18:26: error: expected expression 
    return a.segment<1>(); 
         ^

Tak więc w oparciu o komunikat o błędzie GCC "a.segment" jest wywołaniem funkcji składowej, które nie zawiera nawiasów, co oczywiście zostaje odrzucone. Ale to nie ma sensu, ponieważ nie widzę powodu, by traktować to wyrażenie jako takie. Ponadto, jeśli zmienię M do dowolnej liczby całkowitej na linii 17, jak w przykładzie:

#include <iostream> 

template <typename T, int R> 
class a_type 
{ 
public: 
    template <int N> 
    double segment() 
     { 
      return 42; 
     } 
}; 

template <int M> 
double func() 
{ 
    a_type<double, 58> a; 
    return a.segment<1>(); 
} 

int main(int argc, char *argv[]) 
{ 
    std::cout << func<10>() << std::endl; 
    return 0; 
} 

następnie kod kompiluje i produkuje oczekiwany rezultat.

Byłbym bardzo szczęśliwy, gdyby ktoś mnie oświecił i pokazał, czego tu brakuje.

Odpowiedz

4

Kompilator nie wie, że a.segment jest szablonem (może zależeć od wartości M). Więc trzeba to powiedzieć:

return a.template segment<1>(); 

W drugim przykładzie to wie wszystko o rodzaju a, a więc nie ma problemu.

+0

Wielkie dzięki za odpowiedź! Całkowicie zapomniałem o użyciu słowa kluczowego template. Domyślam się, że moje C++ było trochę zardzewiałe ;-) – Tachikoma

1

Kompilator informuje, że ma problemy z

a_type<double, M> a; 
return a.segment<1>(); 

ponieważ nie może powiedzieć, co członkowie a może mieć, jak to jest szablon (które mogą być specjalnie przystosowane do pewnych wartości M).

main.cpp:18:22: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<' return a.segment<1>(); ^

Jeśli segment jest szablonem, będzie ona traktowana jako segment<1>. Jeśli segment jest zmienną składową a, należy ją skompilować jako a.segment < 1. W jaki sposób kompilator powinien wiedzieć?

Można to naprawić za pomocą

return a.template segment<1>();