小编NoS*_*tAl的帖子

是否可以以编程方式初始化 constexpr std::array 成员

让我们假设我想写一个结构体,它有一个成员 constexpr std::array ,它包含前 N 个 fibs,其中 N 是一个模板参数。

类似这样的东西,但 vals 在编译时可用:

template <int N>
struct first_n_fibs {
    static_assert(N>0);
    static const std::array<int, N> vals;
    static std::array<int, N> init_fibs(){
        std::array<int,N> result;
        if (N==1) {
            return std::array<int,N>{1};
        } else {
            result[0]=1;
            result[1]=1;
            for(int i =2; i<N;++i) {
                result[i]=result[i-2]+result[i-1];
            }
        }
        return result;
    }
};

template<int N>
const std::array<int, N> first_n_fibs<N>::vals=init_fibs();


int main(){
    std::cout << first_n_fibs<2>::vals.back() << std::endl;
    std::cout << first_n_fibs<5>::vals.back() << std::endl;
    std::cout << first_n_fibs<6>::vals.back() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我怀疑没有解决方法,因为 std::array 构造函数不是 constexpr,所以如果有人知道任何涉及 …

c++ constexpr stdarray

3
推荐指数
1
解决办法
3390
查看次数

写作概念的惯用方法,即该类型是std :: vector

我有以下代码实现以下类型特征:

  • 那种类型 std::vector
  • 这种类型是std::vector整数

它有效,但它非常冗长.
是否有更短/更好的方式来使用概念写这个?
我知道我可以从range-v3或其他类似的库中窃取概念,但我们假设我想自己实现它.

#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

template <class T>
struct is_vector {
  static constexpr bool value = false;
};
template <class T, class A>
struct is_vector<std::vector<T, A> > {
  static constexpr bool value = true;
};

template <class T>
struct is_vector_of_int {
  static constexpr bool value = false;
};

template <class A>
struct is_vector_of_int<std::vector<int, A> > {
  static constexpr bool value = true;
};

// TODO add _v bool …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits c++-concepts c++20

3
推荐指数
3
解决办法
202
查看次数

许多嵌套std :: conditional_t的替代品?

我发现许多嵌套的std :: conditional_t难以阅读,所以我选择了一个不同的模式(在自动返回类型的函数上调用decltype):

template<bool is_signed, std::size_t has_sizeof>
auto find_int_type(){
    static_assert(sizeof(int)==4);
    if constexpr(is_signed){
        if constexpr(has_sizeof==4){
            return int{};
        } else if constexpr (has_sizeof==8){
            return std::int64_t{};
        } else {
            return;
        }
    } else {
        if constexpr(has_sizeof==4){
            return (unsigned int){};
        }
        else if constexpr (has_sizeof==8){
            return std::uint64_t{};
        } else {
            return;
        }
    } 
}

static_assert(std::is_same_v<int, decltype(find_int_type<true, 4>())>);
static_assert(std::is_same_v<unsigned int, decltype(find_int_type<false, 4>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 3>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 5>())>);
static_assert(std::is_same_v<std::int64_t, decltype(find_int_type<true, 8>())>);
static_assert(std::is_same_v<std::uint64_t, decltype(find_int_type<false, 8>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 9>())>);
Run Code Online (Sandbox Code Playgroud)

我的问题是:

有没有更好的办法?

编译这种方式比std :: conditional_t慢(假设我需要实例化的类型比我刚才使用内置类型的示例更广泛).

PS这是一个玩具示例,IRCode我会处理一些更复杂的类型.

c++ templates type-traits if-constexpr

3
推荐指数
1
解决办法
92
查看次数

为什么icc会为简单的主要部件生成奇怪的装配?

我有一个简单的程序:

int main()
{
    return 2*7;
}
Run Code Online (Sandbox Code Playgroud)

GCC和clang优化启动时会生成2指令二进制,但icc会产生奇怪的输出.

     push      rbp                                           #2.1
     mov       rbp, rsp                                      #2.1
     and       rsp, -128                                     #2.1
     sub       rsp, 128                                      #2.1
     xor       esi, esi                                      #2.1
     mov       edi, 3                                        #2.1
     call      __intel_new_feature_proc_init                 #2.1
     stmxcsr   DWORD PTR [rsp]                               #2.1
     mov       eax, 14                                       #3.12
     or        DWORD PTR [rsp], 32832                        #2.1
     ldmxcsr   DWORD PTR [rsp]                               #2.1
     mov       rsp, rbp                                      #3.12
     pop       rbp                                           #3.12
     ret
Run Code Online (Sandbox Code Playgroud)

c++ x86 assembly code-generation icc

3
推荐指数
1
解决办法
165
查看次数

使用UINT64_C的目的?

我在boost源中找到了这一行:

const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
Run Code Online (Sandbox Code Playgroud)

我想知道在这里使用MACRO的目的是什么?

所有这一切都是为了增加ULL所提供的常数.

我认为它可能会被用来使人们更难以打字UL而不是打字ULL,但我想知道是否有任何其他理由使用它.

c++ macros

3
推荐指数
1
解决办法
1268
查看次数

在C ++中是否需要布尔值在true时设置为1位/在false时设置为0位

我正在考虑通过使用uint32_t和bool [4]的并集对返回4个bool的函数进行微优化,然后执行popcnt指令以查看bool数组中有多少个元素是正确的。

But I do not know if the standard guarantees that bool is represented as number with only 1 bit set when true and 0 bits set when it is false.

If the answer is no then I have a follow up question: if it is not required is it required that representation is constant, e.g. if I have a test that checks that true bool casted to uint_8t is 1(and 0 for false) does that this means that …

c++ boolean language-lawyer

3
推荐指数
1
解决办法
118
查看次数

我可以使用一些宏在 MSVC 16.6 中恢复删除的 std::result_of 吗?

C++20 模式下的 MSVC 16.6 删除了 C++20 标准中删除的 result_of。我完全赞成做道德上正确的事情,但是我使用的许多 3rd 方库(示例)都失败了。

有时 MSVC 允许用户定义定义,以便仍启用已删除的功能。是否可以选择为 result_of 执行此操作?我已经尝试过 _HAS_FEATURES_REMOVED_IN_CXX20 并且它似乎有效,但是宏以 _ 开头的事实让我感到害怕,这表明它可能是内部 MSVC 机制,而不是用户应该设置的内容。

c++ deprecated visual-c++ c++20 visual-studio-2019

3
推荐指数
1
解决办法
358
查看次数

为什么 std::erase(std::erase_if) 不是 &lt;algorithm&gt; 中适用于任何容器的模板?

std::erase(_if)是对 C++20 的一个很好的补充(终于我可以忘记令人讨厌的擦除删除习惯用法),但有一点很奇怪:从某种意义上说,它不是一种通用算法,它只适用于 std:: 容器,例如它可以不对升压向量进行操作。

    #include<string>

    #include<vector>

    #include<boost/container/vector.hpp>

    int main() {
        std::string str = " Hello World  !";
        std::erase(str, ' '); // :)
        boost::container::vector<int> vi{1,2};
        std::erase(vi, 2); // :(
    }
Run Code Online (Sandbox Code Playgroud)

我最好的猜测是,该算法早在标准中投票概念之前就已经处于实验状态,因此需要进行大量工作来重新设计它,或者担心无法正确指定它的概念(即它会在某些情况下无法正确工作)具有时髦语义的用户定义类型)。

所以:我的问题是为什么这不是具有某些概念(或enable_if)要求/调度(例如地图/集)的通用算法?

c++ stl c++-concepts c++20

3
推荐指数
1
解决办法
248
查看次数

为什么 C++ 要求我在初始化器列表中重复我的基类的模板参数?

我正在将一些代码从 MSVC(没有 permissive-)移植到 linux,我了解到如果在类的初始化列表中调用模板基类的构造函数,则必须指定所有模板参数,否则会出现错误。似乎有点多余,因为如果您在重新输入模板参数时犯了一个错误,那就是一个硬错误:

错误:类型 'Base<int, true>' 不是 'Derived' 的直接或虚拟基数

完整代码在这里:

template <typename T, bool has_x>
struct Base
{
    Base(T t): t_(t){
    }
    T t_=0;
};



template <typename T>
class Derived : public Base<T, false>
{
public:
    // : Base<T, true> is hard error
    Derived(const T& t) : Base<T, false>(t) {}
};

int main()
{
    Derived d(47);
}
Run Code Online (Sandbox Code Playgroud)

这是否有充分的理由,或者只是标准化过程从未花时间处理这个用例的特殊情况?

c++ inheritance

3
推荐指数
1
解决办法
138
查看次数

为什么线程消毒剂会抱怨这个 std::ranges::views::filter 代码?

运行此代码时,线程清理程序会抱怨数据竞争。为什么?

#include <iostream>
#include <ranges>
#include <thread>
#include <vector>

int main(){
    std::vector v{11,22,33,44,55,66};
    auto view = v | std::ranges::views::filter([](const auto x){
        return x>47;
    });
    std::jthread jt1([&]{
    int sum =0;
    for (const auto& val: view) {sum+=val;}
    });    
    std::jthread jt2([&]{
    int sum =0;
    for (const auto& val: view) {sum+=val;}
    });
}
Run Code Online (Sandbox Code Playgroud)

注意:我知道这个答案,我最近在看一个演讲中学到了它,但我发现它非常令人惊讶并且没有与此相关的现有问题,所以我想分享它。如果没有人有兴趣回答,我会自己回答。

c++ race-condition range-v3 c++20

3
推荐指数
1
解决办法
91
查看次数