在C++98标准和C++03标准之间,发生了一个有趣的变化:
struct S {
int S;
};
此代码在 C++03 及更高版本中有效,但在 C++98 中格式错误。具体来说,[class.mem] 第 13 段禁止所有数据成员与 C++98 中的类同名,但这条规则被放宽,这样如果没有用户声明的构造函数,就可以拥有一个非静态的构造函数。同名的数据成员。
这背后的动机是什么?其中涵盖了哪些重要用例需要修改标准?
我有以下代码(https://godbolt.org/z/K7sPbjjKE):
#include <string>
#include <ranges>
#include <vector>
std::vector<std::string> fields;
void insert_many(std::size_t pos, std::span<std::string> keys)
{
auto view = std::views::iota(0uz, keys.size())
| std::views::transform([&](std::size_t i) {
return std::move(keys[i]);
});
static_assert(std::ranges::input_range<decltype(view)>);
fields.insert(fields.cbegin() + pos, view.begin(), view.end());
}
注意:此示例来自https://godbolt.org/z/hYTjsohTf。std::views::iota
我知道,你根本不必在这里使用。问题是为什么当前形式的代码不起作用。
在 libc++ 和 libstdc++ 中,都static_assert
通过了。然而,只有 libc++ 允许调用insert
. 我正在尝试打电话
template< class InputIt > constexpr iterator insert( const_iterator pos, InputIt first, InputIt last );
从错误消息(使用libstdc++)来看,std::ranges::transform_view::iterator
不满足InputIterator,因此无法调用重载:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/bits/stl_vector.h:1484:2: note: candidate template ignored: requirement 'is_convertible<std::output_iterator_tag, std::input_iterator_tag>::value' was not satisfied [with > _InputIterator = _Iterator<false>] 1484 | insert(const_iterator __position, _InputIterator __first, | ^
这是预期的行为吗?我认为新std::views
东西也满足了遗留迭代器的要求。
我有以下代码:
#include <print>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
std::println("{}", v);
}
在这产生的众多错误中,有(clang++ -std=c++23 -stdlib=libc++
,https://godbolt.org/z/3z9Tseh37):
[...]/format_arg_store.h:167:17: error: static assertion failed due to [...]
167 | static_assert(__arg != __arg_t::__none, "the supplied type is not formattable");
| ^~~~~~~~~~~~~~~~~~~~~~~~
这让我很困惑,因为根据cppreference C++23 编译器支持页面,libc++ 支持std::println
并实现P2286: Formatting Ranges。
我做错了什么还是这是标准库错误?