[英]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.