gcc 4.8.1 & clang 3.3,c++11 功能完成,我需要在一些构造像 make_shared/c++14 make_unique 这样的元素的函数中转发 args。但是我对类型推导/转发初始化列表/数组有疑问
我需要的工作示例foo * foo3{ make_it<foo>( {{1,1},{ 10,10 }}, 10 ) };
,因此std::initializer_list
将推断它的参数,函数将转发它们
#include <initializer_list>
#include <algorithm>
struct foo
{
struct pairs{ int a,b; };
foo( int value ){}
foo( std::initializer_list<pairs> elems, int value ){}
};
//some custom allocation mechanizm
char store[sizeof(foo)*2];
char * store_ptr = &store[0];
void * allocfromstore( size_t sz ) { void * ret = store_ptr; store_ptr+= sz; return ret; }
template<typename ValueType, typename ArrType, typename... Args>
ValueType * make_it(std::initializer_list<ArrType> il, Args&&... args)
{
ValueType * obj = new (allocfromstore(sizeof(ValueType))) ValueType( il, std::forward<Args>(args)...);
return obj;
}
template<typename ValueType, typename... Args>
ValueType * make_it(Args&&... args)
{
ValueType * obj = new (allocfromstore(sizeof(ValueType))) ValueType( std::forward<Args>(args)...);
return obj;
}
std::initializer_list<foo::pairs> encapsulate( std::initializer_list<foo::pairs> il ){ return il; }
int main(){
foo * foo0{ make_it<foo>( 10 ) };
foo * foo1{ make_it<foo>( std::initializer_list<foo::pairs>({{1,1},{ 10,10 }}), 10 ) };
foo * foo2{ make_it<foo>( encapsulate({{1,1},{ 10,10 }}), 10 ) };
foo * foo3{ make_it<foo>( {{1,1},{ 10,10 }}, 10 ) };
return 0;
}
实际上 foo3 会因 clang 3.3 而失败:
test.cpp:37:15: error: no matching function for call to 'make_it'
foo * foo3{ make_it<foo>( {{1,1},{ 10,10 }}, 10 ) };
^~~~~~~~~~~~
test.cpp:18:13: note: candidate template ignored: couldn't infer template argument 'ArrType'
ValueType * make_it(std::initializer_list<ArrType> il, Args&&... args)
^
test.cpp:26:13: note: candidate function not viable: requires 0 arguments, but 2 were provided
ValueType * make_it(Args&&... args)
^
1 error generated.
并使用 gcc 4.8.1:
test.cpp: In function ‘int main()’:
test.cpp:37:51: error: no matching function for call to ‘make_it(<brace-enclosed initializer list>, int)’
foo * foo3{ make_it<foo>( {{1,1},{ 10,10 }}, 10 ) };
^
test.cpp:37:51: note: candidates are:
test.cpp:18:13: note: template<class ValueType, class ArrType, class ... Args> ValueType* make_it(std::initializer_list<ArrType>, Args&& ...)
ValueType * make_it(std::initializer_list<ArrType> il, Args&&... args)
^
test.cpp:18:13: note: template argument deduction/substitution failed:
test.cpp:37:51: note: couldn't deduce template parameter ‘ArrType’
foo * foo3{ make_it<foo>( {{1,1},{ 10,10 }}, 10 ) };
^
test.cpp:26:13: note: ValueType* make_it(Args&& ...) [with ValueType = foo; Args = {}]
ValueType * make_it(Args&&... args)
^
test.cpp:26:13: note: candidate expects 0 arguments, 2 provided