我刚刚在 macOS 上安装了 Rustup,并注意到有两个rustc和两个cargo二进制文件:
~/.cargo/bin/rustc (cargo)~/.rustup/toolchains/stable-x86_64-apple-darwin/bin/rustc (cargo)它们的版本完全相同,但diff表明存在一些差异。那么为什么有两种不同的rustc( cargo) 二进制文件,我应该使用哪一种?
我正在玩 C++ 20 范围并注意到一些奇怪的东西(可在https://gcc.godbolt.org/z/4Ycxn88qa重现):
#include <vector>
#include <utility>
#include <string>
#include <ranges>
#include <type_traits>
int main()
{
using KV = std::pair<std::string, std::string>;
std::vector<KV> v;
auto r = v | std::views::filter([](const KV& kv) { return kv.first == "foo"; })
| std::views::transform([](const KV& kv) -> const std::string& { return kv.second; });
for (auto&& val : r) {
static_assert(std::is_same_v<decltype(val), const std::string&>);
}
using R = decltype(r);
using Elem = std::ranges::range_value_t<R>;
static_assert(std::is_same_v<Elem, std::string>); // success
static_assert(std::is_same_v<Elem, const std::string&>); // error
}
Run Code Online (Sandbox Code Playgroud)
我预计最后一个 …
假设我们有以下三个代码片段:
// both a and b are non-volatile ints
a = 123;
b = 456;
Run Code Online (Sandbox Code Playgroud)// both a and b are non-volatile ints
a = rand();
b = rand();
Run Code Online (Sandbox Code Playgroud)cout << "foo" << endl;
cout << "bar" << endl;
Run Code Online (Sandbox Code Playgroud)根据我的理解,(1)中的陈述可以由编制者重新排序,而(2)(3)中的陈述则不能,因为这会改变程序的可观察行为.
但编译器如何知道当事情不是那么"明显"依赖时(例如++a; b = a * 2;明显依赖的陈述)不能重新排序的事情,如(2)(3)中所述?例如,非constexpr功能调用等某些事情可能会阻止重新排序......?
我需要在某些C ++ 11/14代码中使用INVOKE语义(std::invoke在C ++ 17中实现)。我当然不想自己实施它,我相信这将是一场灾难。因此,我决定使用现有的标准图书馆设施。很快我想到的是:
template<typename Fn, typename... Args>
constexpr decltype(auto) my_invoke(Fn&& f, Args&&... args)
noexcept(noexcept(std::bind(std::forward<Fn>(f), std::forward<Args>(args)...)()))
{
return std::bind(std::forward<Fn>(f), std::forward<Args>(args)...)();
}
Run Code Online (Sandbox Code Playgroud)
此实现的问题是,它无法区分左值和右值可调用项(例如,如果函数对象在operator()() &和上重载operator()() &&,则仅&&会调用该版本)。是否有一些库实用程序也可以完美地转发可调用对象本身?如果没有,什么是实现它的好方法?(例如,转发包装器)。
我有这个奇怪的问题,我无法绕过头脑.对于此代码:
struct Foo {
int operator()() const & { return 0; }
double operator()() const && { return 0; }
};
template<typename F>
void test(F&& f)
{
static_assert<is_same<F&&, decltype(f)>::value, "!"); // (1)
// intentionally not forwarding f
using T1 = decltype(f());
using T2 = result_of_t<decltype(f)()>;
using T3 = result_of_t<F&&()>;
using T4 = result_of_t<F&()>;
static_assert(is_same<T1, T2>::value, "!"); // (2)
static_assert(is_same<T1, T3>::value, "!"); // (3)
static_assert(is_same<T1, T4>::value, "!"); // (4)
}
Foo f;
test(f); // all static_asserts passed
test(Foo{}); // (1) and …Run Code Online (Sandbox Code Playgroud) std::for_each 按值接受并返回仿函数:
template< class InputIt, class UnaryFunction >
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );
Run Code Online (Sandbox Code Playgroud)
虽然仿函数可以移入和移出,但我很感兴趣是否根本不涉及对象构造.如果我这样声明我自己my_for_each:
template< class InputIt, class UnaryFunction >
UnaryFunction&& my_for_each( InputIt first, InputIt last, UnaryFunction&& f);
Run Code Online (Sandbox Code Playgroud)
在里面my_for_each,打电话f给std::forward<UnaryFunction>(f)(...),我可以避免移动构造参数的成本,并作为奖励能够尊重ref-qualifiers.但我不确定应该归还什么.如果我做:
return std::forward<UnaryFunction>(f);
Run Code Online (Sandbox Code Playgroud)
可以发生坏事(例如,悬空引用)吗?
标题可能不合适,这里是一个例子:
fn foo(impl Fn(&u32) -> bool) { ... }
foo(|x| *x < 100);
foo(|&x| x < 100);
Run Code Online (Sandbox Code Playgroud)
两个闭包是否传递给foo等效项?我在某些地方看到有人使用第二种形式,但我在官方书中找不到它。这&x部分是一个解构...?
我刚刚了解了C++17中extract添加到std::set/的函数std::unordered_set。我知道这是有效的:
while (!my_set.empty()) {
auto node_handle = my_set.extract(my_set.begin());
auto elem = std::move(node_handle.value());
}
Run Code Online (Sandbox Code Playgroud)
但以下安全吗?(来自/sf/answers/2976399751/)
for (auto it = my_set.begin(); it != my_set.end(); ) {
auto node_handle = my_set.extract(it++);
auto elem = std::move(node_handle.value());
}
Run Code Online (Sandbox Code Playgroud)
我知道extract传递给它的迭代器无效,因此在无效之前extract(it++)将下一个迭代器保存到其中。但是否保证不会使其他迭代器失效?ititextract
我了解匿名命名空间的一般用途是包含仅对当前源(即非标头)文件可见的代码。但是,我无法找到有关以下情况中发生的情况的任何信息:
// In foo.cpp
#include <vector>
// Choice #1
template <typename T>
using Vec1 = std::vector<T>;
// Choice #2
namespace {
template <typename T>
using Vec2 = std::vector<T>;
}
Run Code Online (Sandbox Code Playgroud)
和Vec1有Vec2什么不同吗?由于我想不出一种方法可以在头文件中引用“extern”类型别名Vec1,因此我不确定这里的匿名命名空间是否能实现任何目标。