2017-08-14 115 views
5

有沒有一種方法來編寫一個模板函數,可以在給定的struct的不同成員上運行?結構成員上的模板函數

一個錯誤例子看起來像:

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; 
} 

我想象中的基於交換機上的一個答案,但後來我想,如果這個開關會在運行時進行測試(我想如何避免)還是編譯時?

+1

爲什麼你需要這個? – user0042

+0

我正在求解一個二維網格的耦合偏導數方程組,我想爲每個單元的所有物理量都有一個單一的空間導數函數......或者至少要減少函數的數量來複制/過去! –

+0

似乎多餘和麻煩可能是一個XY問題。 –

回答

10

只要你想拿起從具有相同類型的一組數據成員的數據成員,你可以用一個指針數據成員:

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

而且使用它作爲:

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

如果您還想指出的類型,你可以這樣做:

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

並以此爲:

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

只是出於好奇,第二個片段是即使在C++ 17簡單:

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

看到它運行起來就wandbox;

+0

謝謝!我將採用C++ 17版本! –

+0

當然!我很抱歉,我在前面試過一些鞋子,但花了很長時間才知道該怎麼做......現在可以嗎? –

+0

@valadeaurélien是的。並歡迎SO。 – skypjack

1

您可以利用std::mem_fn,所以你甚至不必去關心:(未經測試)

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()); 

由於您使用的,你可能不小心流...但是這應該添加一點零從寫作cout << obj.fun()開銷。

編輯:mem_fn也適用於數據成員。創建一個可調用函數,返回一個可以使用的值的引用:int x = mem_fn(&pair<int,char>::first)(my_pair);

+0

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

+0

不夠公平。我誤解了答案。謝謝。 – skypjack