2017-08-14 90 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