2017-08-14 24 views
5

Belirli bir struct'un farklı üyeleri üzerinde çalışabilen tek bir şablon işlevini kodlamanın bir yolu var mı? Ben bir anahtar dayanan bir cevap hayalYapı üyeleri için şablon işlevi

struct Foo 
{ 
    int a, b; 
} 

template <MEMBER x> //which does not exist 
cout_member(Foo foo) 
{ 
    cout << foo.x << endl; 
} 

int main() 
{ 
    Foo foo; 
    cout_member<a>(foo); 
    cout_member<b>(foo); 
    return 0; 
} 

, ancak bu anahtar ı önlemek için ne istiyorsunuz (çalıştırma zamanında üzerinde test edilecek olsaydı o zaman merak:

gibi bir yanlış örnek olmazdı) veya derleme zamanında mı?

+1

Neden buna ihtiyacınız var? – user0042

+0

Bir 2D ızgara için birleştirilmiş kısmi türev denklemler sistemini çözüyorum ve her hücrenin tüm fiziksel miktarları için tek bir uzay türevi fonksiyona sahip olmak isterim ... Ya da en azından fonksiyon sayısını azaltmak için kopyala yapıştır ! –

+0

Muhtemelen XY problemi gereksiz ve hantaldır. –

cevap

10

sürece, veri üyesine bir işaretçi kullanabilirsiniz aynı tipte olan veri üyeleri kümesinden veri üyesini almak istediğiniz gibi:

template <int Foo::*M> 
void cout_member(Foo foo) 
{ 
    std::cout << (foo.*M) << std::endl; 
} 

Ve olarak kullanmak:

template <typename T, T Foo::*M> 
void cout_member(Foo foo) 
{ 
    std::cout << (foo.*M) << std::endl; 
} 

Ve olarak kullanabilirsiniz:: Ayrıca türünü belirtmek istiyorsanız

cout_member<&Foo::a>(foo); 

, bunu yapabilirsin

cout_member<int, &Foo::a>(foo); 

Meraktan soruyorum, ikinci pasajı C++ 17'de daha basit olacaktır:

template <auto M> 
void cout_member(Foo foo) 
{ 
    std::cout << (foo.*M) << std::endl; 
} 

it up ve wandbox üzerinde çalışan Bkz; Eğer muhtemelen umurumda değil akışları kullandığınız yana

template < typename Fun, typename ... Params > 
void print(Fun f, Params && ... p) { std::cout << f(std::forward<Params>(p)...) << "\n"; } 

print(std::mem_fn(&Obj::fun), Obj()); 

(denenmemiş) ... ama bu sıfıra küçük eklemek gerekir:

+0

Teşekkürler! C++ 17 sürümünü alacağım! –

+0

Elbette! Kusura bakma, birkaç yıl önce denedim ama nasıl yapılacağını anlayabilmem için uzun zaman aldı ... Şimdi sorun yok mu? –

+0

@ valadeaurélien Yep. Ve SO'ya hoşgeldiniz. – skypjack

1

Sen std::mem_fn kullanmaya devam edebiliyor umurunda gerekmez Sadece cout << obj.fun() yazarak baştan.

Düzenleme: mem_fn veri üyeleri üzerinde de çalışır. Kullanabileceğiniz değere bir başvuru döndüren bir callable oluşturur: int x = mem_fn(&pair<int,char>::first)(my_pair);

+0

@skypjack - http://en.cppreference.com/w/cpp/utility/functional/mem_fn –

+0

Yeterince adil. Cevabı yanlış anladım. Teşekkür ederim. – skypjack

İlgili konular