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 */ }