小编Ziz*_*Tai的帖子

C++ 17 make_optional constexpr-ness

这个页面make_optionalC++ 17 中的函数返回一个constexpr optional<...>.我想(虽然我可能错了)这需要optional<T>有一个constexpr复制或移动构造函数.但是,这个页面也说不是这样的.

我不知道如何make_optional实现目前的C++ 1z草案.请参阅此帖子以获得澄清.是否有一些解决方法,或者它只是标准的草案/ cppreference的错误?

c++ std c++17

7
推荐指数
1
解决办法
415
查看次数

Rustup 与 Cargo 二进制文件

我刚刚在 macOS 上安装了 Rustup,并注意到有两个rustc和两个cargo二进制文件:

  • ~/.cargo/bin/rustc (cargo)
  • ~/.rustup/toolchains/stable-x86_64-apple-darwin/bin/rustc (cargo)

它们的版本完全相同,但diff表明存在一些差异。那么为什么有两种不同的rustc( cargo) 二进制文件,我应该使用哪一种?

rust

6
推荐指数
1
解决办法
2684
查看次数

range_value_t 用于引用类型

我正在玩 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)

我预计最后一个 …

c++ c++20

6
推荐指数
1
解决办法
924
查看次数

可以重新排序的语句

假设我们有以下三个代码片段:

  1. // both a and b are non-volatile ints
    a = 123;
    b = 456;
    
    Run Code Online (Sandbox Code Playgroud)
  2. // both a and b are non-volatile ints
    a = rand();
    b = rand();
    
    Run Code Online (Sandbox Code Playgroud)
  3. cout << "foo" << endl;
    cout << "bar" << endl;
    
    Run Code Online (Sandbox Code Playgroud)

根据我的理解,(1)中的陈述可以由编制者重新排序,而(2)(3)中的陈述则不能,因为这会改变程序的可观察行为.

但编译器如何知道当事情不是那么"明显"依赖时(例如++a; b = a * 2;明显依赖的陈述)不能重新排序的事情,如(2)(3)中所述?例如,非constexpr功能调用等某些事情可能会阻止重新排序......?

c++

5
推荐指数
1
解决办法
305
查看次数

C ++ 11/14 INVOKE解决方法

我需要在某些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()() &&,则仅&&会调用该版本)。是否有一些库实用程序也可以完美地转发可调用对象本身?如果没有,什么是实现它的好方法?(例如,转发包装器)。

c++ c++11 c++14

5
推荐指数
1
解决办法
814
查看次数

正确使用std :: result_of_t

我有这个奇怪的问题,我无法绕过头脑.对于此代码:

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)

c++ c++11 c++14

5
推荐指数
1
解决办法
1261
查看次数

通过普遍参考返回

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,打电话fstd::forward<UnaryFunction>(f)(...),我可以避免移动构造参数的成本,并作为奖励能够尊重ref-qualifiers.但我不确定应该归还什么.如果我做:

return std::forward<UnaryFunction>(f);
Run Code Online (Sandbox Code Playgroud)

可以发生坏事(例如,悬空引用)吗?

(当我for_each这篇文章中设计时,会出现这个问题.)

c++ templates c++11

5
推荐指数
1
解决办法
1138
查看次数

取消引用闭包参数

标题可能不合适,这里是一个例子:

fn foo(impl Fn(&u32) -> bool) { ... }

foo(|x| *x < 100);
foo(|&x| x < 100);
Run Code Online (Sandbox Code Playgroud)

两个闭包是否传递给foo等效项?我在某些地方看到有人使用第二种形式,但我在官方书中找不到它。这&x部分是一个解构...?

rust

5
推荐指数
1
解决办法
154
查看次数

使用迭代器时从 set/unordered_set 中提取

我刚刚了解了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

c++ c++17

5
推荐指数
1
解决办法
624
查看次数

匿名命名空间中的 C++ 类型别名

我了解匿名命名空间的一般用途是包含仅对当前源(即非标头)文件可见的代码。但是,我无法找到有关以下情况中发生的情况的任何信息:

// 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)

Vec1Vec2什么不同吗?由于我想不出一种方法可以在头文件中引用“extern”类型别名Vec1,因此我不确定这里的匿名命名空间是否能实现任何目标。

c++

5
推荐指数
1
解决办法
645
查看次数

标签 统计

c++ ×8

c++11 ×3

c++14 ×2

c++17 ×2

rust ×2

c++20 ×1

std ×1

templates ×1