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

C++ 可变模板与完美转发,c++,c++11,variadic-templates,template-templates,C++,C++11,Variadic Templates,Template Templates,这让我想到了自动化的方法 本质上,我想自动创建函数,如std::make_pair、std::bind1st和std::mem_fun,这样就不必为每个模板类类型编写不同的函数,而可以编写一个可变模板函数,一次处理所有情况。此功能的用法如下所示: make<std::pair>(1, 2); // equivalent to std::make_pair(1, 2) make<std::binder2nd>(&foo, 3); // equival

这让我想到了自动化的方法

本质上,我想自动创建函数,如
std::make_pair
std::bind1st
std::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(1,2)

error: no matching function for call to 'make(int, int)'
这里的语法有错误吗?
或者这是正确的,而GCC是错误的?
或者这在C++0x中根本不可能实现

[编辑]


提案似乎表明这是允许的,这是完全错误的,例如,以“共享”为例。
make_shared
的要点是使用它可以节省运行时的效率。但是如果我尝试使用
make
,会发生什么呢?我不认为那会很有效。或者,如果类型中只有一些构造函数参数是模板参数,而其余的则不是模板参数,那么该如何处理呢?例如,
make(other_vector.begin(),other_vector.end())-迭代器的类型不参与,但您还是传入了它们

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


至于标准,那么,从那时起,它可能很容易被删除。您必须检查FDI。

没错。我希望它能起作用。所以我认为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]$
#包括
模板
TemplateClass make(Args&&…Args)
{
返回模板类(std::forward(args)…);
}
int main(){
make(1,2);
}
// [js@HOST2cpp]$clang++-std=c++0x main1.cpp
// [js@HOST2[cpp]$

这可能是GCC的一个怪癖。我可以使用开发人员快照获得以下内容(我现在没有4.6的副本):

模板<
模板类TemplateClass
,typename。。。Args
,typename结果=TemplateClass
//也适用于可能更正确的
//,typename结果=TemplateClass<
//typename std::Decation::type。。。
// >
>
结果
make(Args&…Args)
{/*和以前一样*/}

我认为存在一个问题,可变模板参数将只匹配可变模板类IIRC。另外,
mem\u fn
bindNth
将被C++0x淘汰和弃用,这要归功于
std::bind
@Xeo:你是说GCC或标准中存在问题?N2555表明它应该是可能的,GCC声称已经在4.4中实现了它(见我的编辑)@Peter:一项提案没有说它已经被FDI采纳(但我确实希望它已经采纳)。让我检查一下。编辑:FDI有提案中的措辞,所以我不知道问题出在哪里。我想知道在如何推导模板参数方面是否存在问题?例如,是否可能是Args最终成为引用类型,从而导致某些SFINAE效应在解析过程中放弃make函数?@PeterAlexander:正如答案所述,这似乎是当前gcc的一个缺陷。供您参考,通过使用辅助(无意义的)类模板,以某种方式对其进行编译。重点不是让函数构造任何类,就像我描述的那样:即模板参数完全来自构造函数参数的类。理论上,可以将该方法专门化为
共享\u ptr
,但总的来说,我同意这会带来更多的问题,而不是解决问题。看来我终于该去看看叮当了:-)
#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]$
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 */ }