2013-03-20 33 views
7

Aplikacja mam na myśli coś podobnego do Vector<size> klasie, w której pragnę oświadczyćCzy można zadeklarować funkcję należącą do pojedynczej instancji klasy szablonów?

CrossProduct(const Vector<size>& other) 

tylko, gdy rozmiar jest 3. Wiem, że istnieją sposoby, można wykraść wokół niego ...

  • zawierać definicję funkcji tylko dla size = 3
  • niech wszystkie inne rozmiary uzyskując błędy linkera
  • czy statyczne dochodzić na początku metody, aby sprawdzić, czy rozmiar jest 3

Czy istnieje sposób, aby prawidłowo zadeklarować funkcję elementu dla konkretnego wystąpienia?

+1

Szukasz wsparcia kompilacji, czy też generowanie błąd czasu zaspokojenia swoich potrzeb? – Porkbutts

Odpowiedz

5

Oto jeden ze sposobów, aby to zrobić:

template <class Type, size_t Size> 
struct EnableCrossProduct 
{ 

}; 

template <class Type> 
struct EnableCrossProduct<Type, 3> 
{ 
    void CrossProduct(const Type & other){} 
}; 

template <size_t Size> 
struct Vector : public EnableCrossProduct<Vector<Size>, Size> 
{ 
}; 
+2

Baw się dobrze powtarzając '// cokolwiek'. – GManNickG

+0

Wolałbym nie pisać ponownie całej klasy, aby dodać jedną lub dwie funkcje. –

+1

@GManNickG Tam idziemy, naprawione –

3

Jeśli możesz uzyskać informacje o rozmiarze podczas kompilacji, możesz użyć std :: enable_if.

template<int N> 
struct Vector 
{ 
    static const int size = N; 
    double data[N]; 
    // ... 

    template<class V> 
    double CrossProduct(const V& other, 
     typename std::enable_if< size == 3 && V::size == 3 >::type* = 0) const 
    { 
     // ... 
     return 0; 
    } 
}; 

void foo(const Vector<3>& v3, const Vector<4>& v4) 
{ 
    v3.CrossProduct(v3); // Ok 
    v3.CrossProduct(v4); // Compile-time error 
} 

może po prostu chcesz, aby ten warunek w enable_if size == V::size.

+0

Zarówno 'CrossProduct (v3)' i 'CrossProduct (v4)' są błędami czasu kompilacji ... jest to funkcja składowa. –

+0

Twój drugi przykład SFINAE nie jest poprawny. Nie powiedzie się na przykład samo utworzenie 'Vector <4>', na przykład, nawet bez próby użycia 'CrossProduct'. Ponadto specjalizacja oznacza powtarzanie informacji ('// ...') lub jej faktoring. – GManNickG

+0

Naprawiono oba problemy. – metal

2

Wolałbym metodę static_assert. Ten

  • prowadzi do najczystszych błędzie
  • jest właściwe, ponieważ nie ma potrzeby SFINAE
  • jest najprostszym sposobem.
+1

Tak ... To jest miłe, ale to niefortunne, że zanieczyszcza Itellisense z Visual Studio. Niewielkie zażalenie, wiem, ale ma to wpływ na użyteczność klasy nieco dla moich celów. –

+0

Są ludzie, którzy nie kodują Intellisense (jak ja). Jeśli używają twojego kodu, musisz również o nich pomyśleć. – ipc

+1

Idealnie byłoby znaleźć rozwiązanie, które pasuje do potrzeb obu stron. Wydaje się jednak, że jest to mało prawdopodobne. Nie zaszkodzi zapytać =) –

Powiązane problemy