C++ 可变模板模板和完美转发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6486432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:14:12  来源:igfitidea点击:

Variadic template templates and perfect forwarding

c++c++11variadic-templatestemplate-templates

提问by Peter Alexander

This questionon the object generator patterngot me thinking about ways to automate it.

这个关于对象生成器模式的问题让我想到了自动化它的方法。

Essentially, I want to automate the creation of functions like std::make_pair, std::bind1stand std::mem_funso that instead of having to write a different function for each template class type, you could write a single variadic template template function that handles all cases at once. Usage of this function would be like:

从本质上讲,我希望自动像功能的建立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);

Is it possible to write this function make? I have tried this, but it doesn't work in GCC 4.5 or 4.6:

可以写这个函数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)...);
}

If I try to call (e.g) make<std::pair>(1, 2)I just get

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

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

Have I got the syntax wrong anywhere here?
Or is this right and GCC is wrong?
Or is this just fundamentally impossible in C++0x?

我在这里的任何地方都弄错了语法吗?
或者这是对的,而 GCC 是错的?
或者这在 C++0x 中根本不可能?

[edit]

[编辑]

Proposal N2555seems to suggest that this is allowed and GCC claims to have implemented it in GCC4.4.

提案N2555似乎表明这是允许的,并且GCC 声称已经在 GCC4.4 中实现了它

采纳答案by Johannes Schaub - litb

That's exactly right. I would expect it to work. So I think that GCC is in error with rejecting that. FWIW:

完全正确。我希望它起作用。所以我认为 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]$

回答by Luc Danton

This is probably a GCC quirk. I can get the following to work with a dev snapshot (I don't have a copy of 4.6 right now):

这可能是 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 */ }

回答by Puppy

This is quite wrong- take make_shared, for example. The point of make_sharedis that there are run-time efficiency savings for using it. But what would happen if I tried to use make<std::shared_ptr>? Don't think that would quite work out. Or how about types where only some of the constructor arguments are template arguments, and the rest aren't? For example, make<std::vector, int>(other_vector.begin(), other_vector.end());- the types of the iterators don't participate, but you pass them in anyway.

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

It's impossible to write a generic makefunction.

写一个泛型make函数是不可能的。

As for the Standard, well, it could easily have been removed since then. You'd have to check the FDIS.

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