Variadic模板模板和完美的转发

时间:2011-06-26 20:11:37

标签: c++ c++11 variadic-templates template-templates

This question上的{p> object generator pattern让我想到了实现自动化的方法。

基本上,我希望自动创建std::make_pairstd::bind1ststd::mem_fun等函数,这样就不必为每个模板类类型编写不同的函数,单个可变参数模板模板函数,可同时处理所有案例。使用这个函数就像:

make<std::pair>(1, 2);         // equivalent to std::make_pair(1, 2)
make<std::binder2nd>(&foo, 3); // equivalent to std::bind2nd(&foo, 3);

是否可以编写此函数make?我试过这个,但它在GCC 4.5或4.6中不起作用:

template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
    return TemplateClass<Args...>(std::forward<Args>(args)...);
}

如果我试着打电话(例如)make<std::pair>(1, 2)我就得到

error: no matching function for call to 'make(int, int)'

我在这里的语法有错吗?
或者这是对的,海湾合作委员会是错的吗? 或者这在C ++ 0x中根本不可能?

[编辑]

提案N2555似乎暗示允许这样做并GCC claims to have implemented it in GCC4.4

3 个答案:

答案 0 :(得分:35)

这是完全正确的。我希望它能起作用。所以我认为GCC拒绝这一点是错误的。 FWIW:

#include <utility>

template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
    return TemplateClass<Args...>(std::forward<Args>(args)...);
}

int main() {
  make<std::pair>(1, 2);
}


// [js@HOST2 cpp]$ clang++ -std=c++0x main1.cpp
// [js@HOST2 cpp]$

答案 1 :(得分:7)

这可能是GCC的怪癖。我可以使用以下代码来处理开发快照(我现在没有4.6的副本):

template<
    template<typename...> class TemplateClass
    , typename... Args

    , typename Result = TemplateClass<Args...>
    // Also works with the arguably more correct
    // , typename Result = TemplateClass<
    //     typename std::decay<Args>::type...
    // >
>
Result
make(Args&&... args)
{ /* as before */ }

答案 2 :(得分:3)

这是非常错误的 - 例如,make_sharedmake_shared的要点是使用它可以节省运行时效率。但是如果我尝试使用make<std::shared_ptr>会发生什么?不要以为那会很有效。或者类型如何只有一些构造函数参数是模板参数,其余的不是?例如,make<std::vector, int>(other_vector.begin(), other_vector.end()); - 迭代器的类型不参与,但无论如何都要传递它们。

编写通用make函数是不可能的。

至于标准,从那以后它很容易被删除。你必须检查FDIS。