[英]Why does the compiler allow vector.begin()=vector.end() in C++?
[英]C++: why does calling std::wstring::begin() before #include <vector> cause a compiler error in this code?
這段代碼:
#include <string>
void blah() {
std::string str;
str.begin();
}
#include <vector>
template <template <class...> class T, class U, class V, class ... Rest>
T<V> foo(const T<U, Rest...> &container, const V &arg) {
(void)container;
return T<V>({arg});
}
int main() {
auto result = foo(std::vector<int>{1, 2, 3, 4, 5}, std::string("asdf"));
return 0;
}
在使用clang編譯時,在第17行(調用foo()
的行foo()
上產生以下錯誤:
main.cpp:17:23: error: no matching function for call to 'foo'
auto result = foo(std::vector<int>{1, 2, 3, 4, 5}, std::string("asdf"));
^~~
main.cpp:11:10: note: candidate template ignored: substitution failure [with T = vector, U = int, V = std::__1::basic_string<char>, Rest = <std::__1::allocator<int>>]: too few template arguments for class template 'vector'
T<V> foo(const T<U, Rest...> &container, const V &arg) {
~ ^
但是,如果我將#include <vector>
移動到文件的頂部,則錯誤消失。
為什么會發生這種情況,有沒有辦法解決這個問題,同時a)保持這些#include
語句的位置,以及b)不必重寫foo
?
這與我正在處理的庫有關,因為它需要在定義調用std::string::begin()
內聯函數的某些其他頭之前包含我的頭。 我想盡可能避免這個要求,特別是因為很可能有人可能會在我之前不加思索地包含這些其他標題(因為通常不需要按特定順序包含標題),導致此錯誤沒有明顯的修復。 令人討厭的“其他標題”在Qt的核心庫中,並包含<QString>
。
我的庫需要定義函數,這些函數采用模板參數,模板參數的數量不確定,因此我使用template <class...> class T
以及為什么我不能重寫foo
。
請注意,似乎唯一具有此問題的STL類是std::vector
。 如果我將第17行更改為使用std::list
, std::set
或其他一個STL容器類,則沒有錯誤。
編輯:由於人們報告其他編譯器沒有拋出錯誤,我將在macOS 10.11.6上添加我的編譯器:Apple LLVM版本8.0.0(clang-800.0.42.1)。
edit2:更新了示例代碼,以更貼近我的實際用例。 在此編輯之前, foo
沒有返回值,但在我的庫中它確實需要依賴於默認模板參數,所以@nm提出的解決方案不幸對我沒有幫助。
您可以像這樣解決此問題:
template <template <class...> class T, class U, class ... Rest>
void foo(const T<U, Rest...> &container) {
(void)container;
}
我不再確定它是編譯器/庫錯誤。 也許情況恰恰相反(即, 不為原始代碼發出診斷消息的編譯器出錯)。 標准的這一部分相當復雜,我不知道如何閱讀它。 無論如何,建議的修復似乎是正確的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.