[英]Can the std::vector range constructor invoke explicit conversions?
以下程序是否格式正確?
#include <vector>
struct A {
explicit A(int) {}
};
int main() {
std::vector<int> vi = {1, 2, 3, 4, 5};
std::vector<A> va(vi.begin(), vi.end());
}
根據 C++17 [sequence.reqmts],要求
X u(i, j);
其中X
是一個序列容器,是:
T
應該是EmplaceConstructible
到X
從*i
。
但是,在前一段中指出:
i
和j
表示滿足輸入迭代器要求的迭代器,並指代可隱式轉換為value_type
的元素,
因此,在我看來,這兩個要求都需要滿足:范圍的值類型必須隱式轉換為容器的值類型,並且EmplaceConstructible
必須滿足(這意味着分配器必須能夠執行所需的初始化)。 由於int
不能隱式轉換為A
,因此該程序應該是格式錯誤的。
然而,令人驚訝的是,它似乎在 GCC 下編譯。
僅需要序列容器支持從滿足隱式可轉換標准的迭代器構造。
據我所知,這本身並不禁止序列容器支持不滿足該標准的迭代器的構造1 。 對此有明確的規定:
如果構造函數... 使用不符合輸入迭代器條件的InputIterator 類型調用,則構造函數不應參與重載決議。
目前尚不清楚“有資格作為輸入迭代器”在上下文中的確切含義。 是表達 Cpp17InputIterator 的非正式方式,還是試圖引用 i 和 j 的要求? 我不知道。 無論是否允許,標准對檢測它都沒有嚴格的要求:
[container.requirements.general]
某些容器成員函數和推導指南的行為取決於類型是否有資格作為輸入迭代器或分配器。 未指定實現確定類型不能作為輸入迭代器的程度,但至少整數類型不應作為輸入迭代器。 ...
由於任何 Cpp17InputIterator “有資格作為輸入迭代器”的解釋,示例程序將不需要格式錯誤。 但也不能保證格式正確。
1在這種情況下,在依賴它時發出警告可能會被視為實施質量問題。 另一方面,這種對隱式轉換的限制可能被認為是一個缺陷。
PS 這在 Clang(使用 libc++)和 Msvc 中編譯時也沒有警告。
PPS 這個措辭似乎已經添加到 C++11 中(這是很自然的,因為當時還引入了顯式構造函數)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.