2014-11-03 73 views
1

我正在浏览一些模板示例代码,还有一件事我不明白。需要关于C++模板格式的说明

取模板梅索德:

template<class Seq, class T, class R> 
void apply(Seq &sq, R(T::*f)() const) { 
    typename Seq::iterator it = sq.begin(); 
    while(sq.end() != it) { 
     ((*it++)->*f)(); 
    } 
} 

样本类:

class MyClass {  
public: 
    MyClass() {} 
    void doSomething() const { 
     std::cout << "doing stuff..." << std::endl; 
    } 
}; 

并测试代码:

void testMyClass() { 
    vector<MyClass*> v; 
    for(size_t i = 0; i < 5; ++i) { 
     v.push_back(new MyClass()); 
    } 
    // call a member methode on all elements in container 
    apply(v, &MyClass::doSomething); 
} 

我将不胜感激,如果有人可以解释我是什么那class R,就像在模板定义中定义的那样?

回答

2

class R指向传递给函数apply的函数指针的返回类型。它会自动从实际传递的函数指针类型中推导出来,所以当调用apply时,您从不需要关心它。

apply丢弃函数的返回值,实现这样你就可以简单地强制传递函数返回void

template<class Seq, class T> 
void apply(Seq &sq, void(T::*f)() const) { 
    typename Seq::iterator it = sq.begin(); 
    while(sq.end() != it) { 
     ((*it++)->*f)(); 
    } 
} 

但是,现在你限制呼叫现场只有通过这样的函数指针。可悲的是,一个函数返回的指针不是可以转化为一个没有的,尽管它会非常“直观”。

所以,当你把一个函数指针作为参数,并且你不关心返回类型时,最好接受“any”返回类型比“none”更好。

2

class R在模板中用于推导函数的返回类型。在你的情况下,它被推断为void类型。

+1

你不知道由于我们还没有给出'Gromit :: doSomething'的定义,推导出的返回类型是'void'。给定的代码不应该编译。 – 2014-11-03 22:32:41

+2

@CrazyEddie,非常有洞察力。我希望OP意味着使用'&MyClass :: doSomething'或打算使用'Gromit'而不是'MyClass'。 – 2014-11-03 22:36:29