2015-02-07 47 views
1

社區! 我想申請新的C++ 14的功能和錯誤時遇到意外,而我正在試圖通過爲const char []函數參數下面給出:C++ 14自動扣除錯誤:函數返回數組

decltype(auto) autofunc(const auto& a) 
{ 
    cout<<"Hello World\n"; 
    cout<<a<<endl; 

} 


auto lambd = [](const auto& word){ autofunc(std::forward< decltype(word) > (word));}; 

int main() 
{ 


lambd("Goodbye World\n"); 


    return 0; 
} 

我不知道爲什麼,但編譯器的消息是該函數試圖返回一個數組(爲什麼會這樣做?)。如果我將函數的返回類型更改爲void它將被編譯。如果我傳遞另一種類型的參數(不是數組),它將被編譯。數組有什麼問題?

錯誤消息

../../untitled6/main.cpp: In instantiation of '<lambda(const auto:3&)> [with auto:3 = char [15]]': 
../../untitled6/main.cpp:74:25: required from here 
../../untitled6/main.cpp:68:84: error: no matching function for call to 'autofunc(const char [15])' 
    auto lambd = [](const auto& word){ autofunc(std::forward< decltype(word) > (word));}; 
                        ^
../../untitled6/main.cpp:68:84: note: candidate is: 
../../untitled6/main.cpp:60:17: note: template<class auto:2> decltype(auto) autofunc(const auto:2&) 
    decltype(auto) autofunc(const auto& a) 
       ^
../../untitled6/main.cpp:60:17: note: template argument deduction/substitution failed: 
../../untitled6/main.cpp: In substitution of 'template<class auto:2> decltype(auto) autofunc(const auto:2&) [with auto:2 = char [15]]': 
../../untitled6/main.cpp:68:84: required from '<lambda(const auto:3&)> [with auto:3 = char [15]]' 
../../untitled6/main.cpp:74:25: required from here 
../../untitled6/main.cpp:60:17: error: function returning an array 
+0

什麼是'functor'?什麼是'f'?什麼是確切的問題/錯誤信息?你使用什麼版本的編譯器? – ildjarn 2015-02-07 09:29:38

+0

@ ildjarn,哦,對不起。 * functor *是不必要的對象,我忘了消除它。我使用的編譯器是G ++ - 4.9。錯誤消息,我添加到問題。 – GamovCoder 2015-02-07 09:33:45

+3

您不允許在函數參數的聲明中使用'auto'。 'decltype(auto)autofunc(const auto&a){...}'是無效的C++ 14。 – 2015-02-07 09:41:53

回答

5

這是一個GCC錯誤。

auto在C++ 14中的函數參數聲明中是不允許的。這個語法由Concepts Lite TS添加。 GCC 4.9 release notes

G++ supports unconstrained generic functions as specified by §4.1.2 and §5.1.1 of N3889: Concepts Lite Specification. Briefly, auto may be used as a type-specifier in a parameter declaration of any function declarator in order to introduce an implicit function template parameter, akin to generic lambdas.

N3889是概念TS的早期工作草案。引用的章節5.1.1的部分內容如下

A generic function is denoted by function declarator having auto or a concept-name as part of the type-specifier in its parameter-declaration-clause. [Example:

auto f(auto x); // Ok 
void sort(Sortable& c); // Ok (assuming Sortable names a concept) 

end example ]

The use of auto or a concept-name in the parameter-declaration-clause shall be interpreted as the use of a type-parameter having the same constraints and the named concept. [ Note: The exact mechanism for achieving this is unspecified. — end note ] [Example: The generic function declared below

auto f(auto x, const Regular& y); 

Is equivalent to the following declaration

template<typename T1, Regular T2> 
auto f(T1 x, const T2&); 

end example ]

請注意,此轉換不應影響返回類型;它仍然是auto - 意味着它會被推斷出來。

鑑於這些規則,autofunc的聲明應該已經相當於

template<class T> 
decltype(auto) autofunc(const T& a) { /* ... */ } 

這將一直有效。相反,它得到了解釋爲

template<class T> 
T autofunc(const T& a) { /* ... */ } 

導致一個錯誤,因爲,所有你正在做的轉發,T最終得到推斷爲數組類型。

這是特別具有諷刺意味,因爲GCC 4.9的自己的筆記(同上)說,

// the following two function declarations are equivalent 
auto incr(auto x) { return x++; } 
template <typename T> 
auto incr(T x) { return x++; } 

這是demonstrably not the case在GCC 4.9。

2
error: no matching function for call to 'func(const char [15])' 
    auto lambd = [](const auto& word){ func(word);}; 
              ^
note: candidate is: 

template<class auto:1> 
decltype(auto) func(const auto:1&) 

decltype(auto) func(const auto& a) 
      ^

是你得到的錯誤。它表示返回類型與參數相同。那是因爲你有decltype(auto)和執行替換「功能」與:

template<class T> 
T func(const T& a) 

代替:

template<class T, class R> 
R func(const T& a); 

爲什麼它這樣做,我沒有解釋..但錯誤本身是明確。一旦

#include <iostream> 

using namespace std; 

decltype(auto) func(const auto &a) 
{ 
    cout<<"Hello World\n"; 
    cout<<a<<endl; 
} 


auto lambd = [](const auto word){ func(std::forward<decltype(word)>(word));}; 

int main() 
{ 
    lambd("Goodbye World\n"); 
    return 0; 
} 

,你讓它const reference,它不會工作:

這工作得很好。我仍然不知道爲什麼。

編輯:

我可以得到它的所有工作的唯一辦法就是要做到:

#include <iostream> 

using namespace std; 

decltype(auto) func(const auto &a) 
{ 
    cout<<"Hello World\n"; 
    cout<<a<<endl; 
} 


auto lambd = [](const auto &word){ func(std::forward<decltype(word)>(word));}; 

int main() 
{ 
    lambd((const char*)"Goodbye World\n"); 
    return 0; 
} 

阿卡創建的字符串一個臨時變量並傳遞,與其..或鑄造參數指向char數組的指針。看起來很難判斷它是「const char [15]」還是「const char *」。

無論哪種方式,上述將工作。

+0

目前還不清楚爲什麼這個beahavour只關注數組,因爲函數只有在傳遞一個數組時纔會這樣。在其他情況下,它被編譯... – GamovCoder 2015-02-07 09:42:58

+0

是的,只要你改變* auto&*到* auto *(無論這個改變應用到func還是lambd都無所謂),它編譯得很好 – GamovCoder 2015-02-07 09:53:47

+0

得到它的工作。只需將該參數強制轉換爲指向char數組的指針即可。或者爲該字符串創建一個臨時變量並將該變量作爲參數傳遞。 – Brandon 2015-02-07 09:55:39