2011-11-02 16 views
5

Bu gibi bir şablon temel sınıfım var:Temel ve türetilmiş türlere templated bir işlevi sınırlandırın mı?

template<typename T, std::size_t Size> 
class VectorT 
{ 
public: 
    typedef T data_type; 
} 

ve birkaç uzman türetilmiş sınıf:

template<typename T> 
class Vector2d : public VectorT<T, 2U> 
{ // some specialised functions } 

template<typename T> 
class Vector3d : public VectorT<T, 3U> 
{ // some other specialised functions } 

ve bunlar iyi çalışıyor. Howerver, operatörler için birkaç bağımsız fonksiyonum var. Örneğin:

template<typename T, size_t Size> 
VectorT<T, Size> operator*(T lhs, const VectorT<T, Size>& rhs) 
{ 
    ... 
} 

Ne yazık ki bunlar türetilmiş sınıflarım için çalışmazlar, çünkü Vector2d<T> yerine VectorT<T, Size> döndürüyorlar.

template<V> 
V operator*(typename V::data_type lhs, const V& rhs) 
{ 
    ... 
} 

ile çalıştım ve bu durum gayet iyi çalışıyor, ancak belirsizliğe yol açabiliyor çünkü bir data_type üyesi ile başka herhangi bir şeye batıyor.

Bunu nasıl bulabilirim: yalnızca vektör tabanım veya herhangi bir türeviyle çalışan güvenli tip fonksiyonlar yazabilirim?

Alt sınıflar için tekrar operatörleri yeniden tanımlamak ve yeniden tanımlamak zorunda kalmaya çalışıyorum.

cevap

7

Henüz başka temel sınıf, şablon parametreleri bağımsızdır tane ekleyin ve bu bazdan türetilen dışındaki türleri için görüşmelerini devre dışı bırakmak SFINAE kullanabilirsiniz Bu işlev, gerekenden daha fazla bir tür, yani VectorBase taban sınıfı için çalışacaktır.

TR1'i uygulayan bir derleyici kullanıyorsanız, kullanılan her iki yerde için boost::'u değiştirebilirsiniz.

+1

Teşekkür ederim, bu gece bana SFINAE ile ilgili bir cevap verdiğiniz ikinci kez; Bildiğim kadarıyla bilgimdeki boşluklar burada! Ben kesinlikle enable_if'in nasıl çalıştığından tam olarak emin değilim, ama bu gerçekten işe yaradı. Tekrar teşekkürler. – DanDan

+0

@Kballo: boost :: 'by“ std :: '- - ile ilgili olarak' std :: enable_if' 'boost :: enable_if_c' için kesin bir eşdeğerdir, dolayısıyla' 'unwrap' ' std :: 'konumuna geçtiğinizde' is_base_of' değerinin kendisinin değeri. –

1

"Hoş" bir yolun olmadığı sıra dışı bir durumdasınız. Şunları yapabilirsiniz:

  1. Kontrol zamanında tip
  2. bir VectorT<>& ve kullanımını alın (ya da zaman derlemek, boost muhtemelen bunu yapabilir) yerine işlevi içinde yeni VectorT oluşturma ve geri dönme. Bu şekilde VectorT'un alt sınıflarını da referans alarak alabilirsiniz. Bu, bir işleç yerine bir işlev kullanmak zorunda kalmanızı sağlar.
  3. K-ballo ne dedi.
+1

En çok seçenek 3'ü severim: P –

İlgili konular