lambda作为模板参数,可以访问'this'指针吗?

时间:2012-01-15 00:12:16

标签: c++ templates c++11 lambda

我必须创建三到四个类的对象,所有这些对象都继承自一个基类,但是一些对象需要具有不同的行为 - 比如完全改变一个函数;我可以通过更多的继承和多态来做到这一点,但这似乎不是一个好主意。

我的第一个解决方案是使用专门的模板(对于每个非标准的情况),但后来我将lambdas作为模板参数(例如:Can we use a lambda-expression as the default value for a function argument?)并使用它们代替类方法(如下所示:C++11 lambda and template specialization ) - 对我来说这是更好的解决方案,因为我只需要为每种奇怪的情况传递lambda:

auto default_lambda = [&]() -> int {return this->Sth;};
template<typename functor = decltype(default_lambda)>
class SomeClass{
...

问题在于这个指针 - 我想要更改的方法需要访问非静态方法,而lambda是在非静态方法之外定义的。而且,我不能将类的引用传递给lambda,因为它是一个模板类(或者我错了?)。
当然,我可以使用专门的模板或只是函数指针,但我真的很喜欢lambdas的解决方案,我认为它比我的其他想法更好。
有没有办法“避免”这个问题?或许我的想法一直很糟糕?

2 个答案:

答案 0 :(得分:2)

您的方法至少存在三个明显的问题:

  1. 班级SomeClass无法访问私人会员,即使用this是不可能的。
  2. 您尝试从上下文绑定this,但没有任何上下文,即没有任何绑定。您必须传递对象以处理函数参数。
  3. 您只指定了一种函数对象但没有实例,即稍后您将无法使用它。
  4. 那就是说,似乎你可以使用自定义函数对象类型的类型而不是一些lambda函数(当然,这绝对是不合理的,但实际上它确实有效):

    struct default_lambda {
        template <typename T>
        int operator()(T const& o) const { return o.x(); }
    };
    template <typename F = default_lambda>
    class SomeClass {
        ...
    };
    

答案 1 :(得分:0)

如果您需要完全更改一个功能,您有两个选择:

  • 一个虚函数,如果你有很多这样的对象并且你不想创建许多名称空间范围类型,可能使用本地类+类型擦除:
  • std::function,如果你愿意,可以稍后反弹。

第一个解决方案的示例代码(您甚至可以将其设为模板):

std::unique_ptr<my_base2> get_an_object()
{
    class impl : public my_base2
    {
        void my_virtual_function() { blah blah; }
    };

    return std::unique_ptr<my_base2>(new impl);
}

在这种情况下,两者通常都优于模板(但没有上下文,很难分辨)。