函数参数的默认值,它是指向成员的指针

时间:2015-01-31 10:24:16

标签: c++ c++11 delegates variadic-templates member-function-pointers

我正在尝试使用可变参数模板为函数实现装饰器。并尝试最小化重载次数,因为它减少了模板参数deducion失败时编译器错误消息的大小。我有实现,它适用于任何类的任何成员(使用委托Ret(Ctx :: *成员)(Args ...))和一个额外的重载,它不会将指针指向成员函数,只调用第一个版本传递& CTX :: opeator()。我试图通过在这里添加成员指针参数的默认值来删除额外的重载。这是编译的版本:

template<
    typename Decorator,
    typename Ctx, typename R, typename... Args,
    typename... CTorArgs
>
Decorator decorate(
    CTorArgs&&...cargs,
    const Ctx &obj, R (Ctx::*member)(Args...) const = &Ctx::operator()
) {
    return Decorator(
        std::function<R(Args...)>([&obj, member](Args... args){
            return (obj.*member)(args...);
        }),
        std::forward(cargs)...
    );
}

但是没有明确的成员函数规范就无法调用它。这是我现在正在玩的一个例子:

struct IntDecorator {
    IntDecorator(std::function<std::string(std::string)> func): 
        m_func(func) {}

    std::string operator() (int val) {
        std::ostringstream oss;
        oss << val;
        return m_func(oss.str());
    }
private:
    std::function<std::string(std::string)> m_func;
};

struct PrefixAdder {
    PrefixAdder(std::string prefix): m_prefix(prefix) {}
    std::string addPrefix(std::string val) const {return m_prefix + val;}
    std::string operator() (std::string val) const {return m_prefix + val;}
private:
    std::string m_prefix;
};

int main(int, char**) {
    PrefixAdder p("+++> ");
    std::cout << decorate<IntDecorator>(p, &PrefixAdder::addPrefix)(123) << std::endl;
    std::cout << decorate<IntDecorator>(p, &PrefixAdder::operator())(123) << std::endl;
    std::cout << decorate<IntDecorator>(p)(123) << std::endl; // compilation error
}

编译器不能推导出类型R(成员函数返回类型)。代码在添加额外的重载后工作,我试图消除或通过指定所有模板参数甚至比额外的重载更糟糕:

template<typename Decorator, typename Ctx, typename... CTorArgs>
Decorator decorate(CTorArgs&&...cargs, const Ctx &obj) {
    return decorate<Decorator>(cargs..., obj, &Ctx::operator());
}

如果没有附加版本的装饰模板,我可以自动减少类型吗?在C ++ 11中自动推断类型有什么问题?

编辑:我最初的目标是获得更好的错误消息,并且我已经使用类型特征和static_assert实现了它。所以这个问题现在更具理论性和实用性。如果有人知道如何编写一个涵盖委托和仿函数的实现,你可以提供答案,我会接受它。

0 个答案:

没有答案
相关问题