4

令人困惑的标题,希望一些代码可以澄清:

struct MyNestedType {
    void func();
};

struct MyType {
    MyNestedType* nested;
}

std::vector<MyType> vec;

// ... populate vec

// I want something approximating this line, but that doesn't use made-up C++!
std::for_each(vec.begin(), vec.end(), std::mem_fun_ref(&MyType::nested->func));

所以基本上我想在容器的每个元素上调用一个方法,但它实际上不是类型的方法,它是包含类型的一些方法......我知道我可以编写一个函数对象来“传递”调用但是我想调用一些方法,这会变得一团糟。

有任何想法吗?

4

6 回答 6

6

为什么不使用简单的 for 循环?

for(vector<MyType>::iterator i = vec.begin(); i != vec.end(); ++i)
    i->nested->func();

或者,您可以使用 lambda 表达式或 boost::foreach

FOREACH(MyType x, vec)
    x.nested->func();

您可以使用 binders 和 mem_funs 构建您的表达式,但这会变得非常混乱和混乱!将所有内容放在一个 std::foreach 行中没有任何优势。

于 2009-05-13T13:14:24.593 回答
3

你可以使用这样的函子

template <typename T, T* MyType::* TMember, void (T::* TNestedMember)() >
struct Caller {
    Caller() {
    }

    template <typename TObject>
    void operator()(TObject object) {
        (object.*TMember->*TNestedMember)();
    }
};

解决您的问题

struct MyNestedType {
    MyNestedType(int a):
        a_(a){
    }
    void func() {
        std::cout << "MyNestedType::func " << a_ << std::endl;
    }
    void foo() {
        std::cout << "MyNestedType::foo " << a_ << std::endl;
    }
    int a_;
};
struct MyType {
    MyNestedType* nested;
};

int main()
{
    std::vector<MyType> vec;

    std::auto_ptr<MyNestedType> nt1(new MyNestedType(2));
    std::auto_ptr<MyNestedType> nt2(new MyNestedType(5));
    MyType t1 = {nt1.get()};
    MyType t2 = {nt2.get()};

    vec.push_back(t1);
    vec.push_back(t2);

    std::for_each(vec.begin(), vec.end(), 
                  Caller<MyNestedType, &MyType::nested, &MyNestedType::func>());
    std::for_each(vec.begin(), vec.end(), 
                  Caller<MyNestedType, &MyType::nested, &MyNestedType::foo>());
}
于 2009-05-13T13:43:53.703 回答
2

也许你可以将 func() 添加到 struct MyType() 中:

void func(...) {
   nested->func(...);
}

这样,您将没有单独的适配器仿函数,而是在包装器类型中进行聚合,即非常常规的 OOP 技术。

于 2009-05-13T13:25:47.460 回答
2

如果你想使用 for_each 你需要一个仿函数。

struct CallMyFunc
{
    void operator()(MyType& obj)    {   obj.nested->func();}
};


std::for_each(vec.begin(), vec.end(), CallMyFunc());

或者,我会使用以下描述的 boost::FOREACH 语法:

Dario:用for_each调用容器元素成员的成员函数?

于 2009-05-13T13:39:10.480 回答
2

是的,可以使用boost::bind它,但它会变得混乱。boost::bind请使用@Dario's boost for-each方式,但为了完整起见,这里是一个

std::for_each(vec.begin(), vec.end(), 
    boost::bind(&MyNestedType::func, boost::bind(&MyType::nested, _1)));

无论如何,碰巧的是,我们甚至没有得到一个很好的单线:)

于 2009-05-13T14:38:46.920 回答
0

使用Boost的transform_iterator怎么样?

于 2009-05-13T13:08:42.120 回答