gcc 4.8.1 &鏗鏘3.3,C++ 11功能齊全, 我需要在某些函數中轉發args,構造像make_shared/C++ 14 make_unique這樣的元素。但我有問題類型推演/轉發初始化列表/陣列完美轉發,可變參數模板,initializer_list - 一起
我需要工作的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將失敗,鐺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
但我想知道爲什麼它不能使用未命名的結構,excalty作爲構造函數的作品。 initializer_list –
@ArturBac編譯器無法判斷「{{0,0},{1,1}}是否爲'std :: initializer_list>'或' std :: initializer_list >',或'std :: intializer_list ',... –
Casey
是的,我知道它不能確定它是結構體,所以它是完美轉發邏輯中的一個洞,我被設計爲轉發構造函數的參數,並且有些情況下它不能被使用。 如果我們告訴編譯器名爲struct(足以僅列出列表中的第一個結構體),那麼這將起作用: foo * foo3 {make_it({foo :: pairs {1,1},{10,10}}} ,10)}; –