标签: constexpr

如何在 C++ 中实现两个向量的编译时乘积

大小为“N”的两个向量的标量积定义为 SP(a, b) = a_1 * b_1 + ... + a_N * b_N。

编译时整数向量定义为:

template<int... I>
struct Vector;
Run Code Online (Sandbox Code Playgroud)

功能产品界面:

template<typename Vector1, typename Vector2>
constexpr int product
Run Code Online (Sandbox Code Playgroud)

例如,可以使用以下代码进行测试:

static_assert(product<Vector<1, 2, 5>, Vector<1, 3, 4>> == 27);
Run Code Online (Sandbox Code Playgroud)

如何实现产品才能匹配上面的断言和接口?

c++ templates compile-time constexpr

4
推荐指数
1
解决办法
711
查看次数

C++ 概念,如何检查 constexpr static int 是否等于 1,或类似...?Clang 不同意 GCC 和 MSVC

我无法在cpprefference上找到与成员匹配的概念的正确语法static constexpr。此代码可以在 GCC 和 MSVC 上编译并正常运行,但在 Clang 中不起作用。我想知道是否有人知道这是我的错误,还是 GCC 和 MSVC 或 Clang 的问题?这是所有三个编译器都打开的Godbolt,我认为它说明了这一点!

#include <concepts>
#include <iostream>

template<typename T>
concept MyConcept = requires (T t){
    requires t.member == 1;

    //[clang's error]
    // note: because 't.member == 1' would be invalid: 
    //       constraint variable 't' cannot be used in an evaluated context
};

struct S {
    constexpr static int member {2};
};
struct D {
    constexpr static int member {1};
};

template<MyConcept …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++-concepts c++20

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

如何在 C++ 中显式实例化模板 constexpr 变量?

如果有一个模板 constexpr 变量(例如用于计算斐波那契数列)并且想要为某些模板参数实例化它,则constexpr在实例化期间必须重复关键字吗?

template<int N> constexpr size_t fib = fib<N-1> + fib<N-2>;
template<> constexpr size_t fib<1> = 1;
template<> constexpr size_t fib<2> = 1;

//template constexpr size_t fib<70>; // GCC error
template size_t fib<70>; // Clang error
Run Code Online (Sandbox Code Playgroud)

这里的问题是 GCC 坚持删除关键字:

error: explicit instantiation shall not use 'constexpr' specifier
Run Code Online (Sandbox Code Playgroud)

而 Clang 坚持保留它:

error: type 'size_t' (aka 'unsigned long') of explicit instantiation of 'fib' does not match expected type 'const size_t' (aka 'const unsigned long')
Run Code Online (Sandbox Code Playgroud)

演示: https: //gcc.godbolt.org/z/f6rMjz95E

根据标准,哪个编译器是正确的?

c++ language-lawyer constexpr explicit-instantiation

4
推荐指数
1
解决办法
270
查看次数

编译器无法执行 constexpr 表达式

我有这样的代码:

template<typename ... Args>
constexpr size_t get_init_size(Args ... args) {
    return sizeof...(Args);
}

template<typename ... Args>
constexpr auto make_generic_header(Args ... args) {
    constexpr size_t header_lenght = get_init_size(args...);
    return header_lenght;
}

constexpr auto create_ipv4_header() {
    constexpr auto x = make_generic_header(0b01, 0b10, 0b01);
    return x;
}
Run Code Online (Sandbox Code Playgroud)

我知道这是虚拟代码,但我将其隔离以查找错误。

编译器给我错误(GCC):

In instantiation of 'constexpr auto make_generic_header(Args&& ...) [with Args = {int, int, int}]':
/tmp/tmp.CaO5YHcqd8/network.h:39:43:   required from here
/tmp/tmp.CaO5YHcqd8/network.h:31:22: error: 'args#0' is not a constant expression
   31 |     constexpr size_t header_lenght = get_init_size(args...);
      |                      ^~~~~~~~~~~~~ …
Run Code Online (Sandbox Code Playgroud)

c++ templates constexpr c++17 constexpr-function

4
推荐指数
1
解决办法
616
查看次数

解决与封闭类具有相同类型的“constexpr”静态数据成员的限制

constexpr我想为一个类提供Color如下功能:

// color.hpp
struct Color
{
    Color(int r, int g, int b, int a);
    static const Color Red;
    // ...
};



// color.cpp
Color::Color(int r, int g, int b, int a) { /* ... */ }
const Color Color::Red(255, 0, 0, 255);
// ...
Run Code Online (Sandbox Code Playgroud)

我的愿望是保持此类的 API 不变,因此我想完全删除color.cpp并对头文件进行以下更改:

// color.hpp
struct Color
{
    constexpr Color(int r, int g, int b, int a) { /* ... */ }
    inline static constexpr Color Red{255, 0, 0, 255};
    // …
Run Code Online (Sandbox Code Playgroud)

c++ static initialization constexpr c++17

4
推荐指数
1
解决办法
516
查看次数

非 constexpr 类的 Constexpr 方法

如果类没有任何 constexpr 构造函数,是否有任何理由将 constexpr 添加到类的方法中?也许编译器在这种情况下可以做一些优化?

c++ optimization class constexpr

4
推荐指数
1
解决办法
159
查看次数

在编译时生成位掩码

我想在编译时生成各种位掩码:

0x11111111或者0x1111111111111111

0xF0F0F0F0或者0xF0F0F0F0F0F0F0F0

大小取决于类型,是 32 位还是 64 位。

前任:

template <typename T> genMask(unsigned char templt) {
  ....
};

genMask<uint32_t>(0xF0);
genMask<uint64_t>(0xF0);
Run Code Online (Sandbox Code Playgroud)

第一次调用应该生成0xF0F0F0F0,而第二次调用 genMask 应该生成0xF0F0F0F0F0F0F0F0

目前我已经对这些进行了硬编码。

这里的任何想法将不胜感激。

编辑:这是一种老式的做法:

#define MASK(b) ((T(-1) / 0xFF) * (b))

其中 T 是类型。

c++ bit-manipulation constexpr

4
推荐指数
1
解决办法
264
查看次数

有没有办法检测可以标记为“constexpr”的函数?

鉴于我想改进我的 C++ 代码库。第一步是将函数标记为constexpr满足所用 C++ 标准的要求。有没有办法判断一个函数是否可以被标记constexpr

我想出的唯一方法是添加constexpr到单个实例,运行编译器,并检查它是否抱怨它不是constexpr。重复直到检查完所有实例。这种方法无法扩展。

相关:我们应该尽可能使用 constexpr 吗?

c++ constexpr

4
推荐指数
1
解决办法
174
查看次数

计算可变参数模板的函数

我试图弄清楚哪种是在变量类型列表上实现函数的最惯用的方式.例如,计算所有类型的最大大小.我知道有几种方法可以完成这样的任务,但我想知道何时选择哪种策略.

这些是我会考虑的机制(可能存在更多,如果是这样,请提及):

  • 输入特征(理想情况下使用声明):

    template <typename Head>
    using max_size = typename std::integral_constant<size_t, sizeof(Head)>::type;
    
    template <typename Head, typename... Tail>
    using max_size = ?;
    
    Run Code Online (Sandbox Code Playgroud)
  • constexpr 功能:

    template <typename Head>
    constexpr size_t max_size() { return sizeof(Head); }
    
    template <typename Head, typename... Tail>
    constexpr size_t max_size() { ? }
    
    Run Code Online (Sandbox Code Playgroud)

我的问题是双重的:

  1. 计算的哪些特征决定了选择什么策略?

  2. 在每种情况下,上述最大尺寸示例的示例实现如何?

c++ variadic-functions variadic-templates constexpr c++11

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

C++标准是否通过constexpr成员函数指针明确禁止调用中的默认参数?

请考虑以下代码:

struct foo {
    int bar(int, int = 0) {
        return 0;
    }
};

constexpr auto ptr = &foo::bar;

int main() { 
    return (foo{}.*ptr)(0);
}
Run Code Online (Sandbox Code Playgroud)

正如所料,此代码无法使用最新版本的GCC,Clang和MSVC进行编译.

但是,假设的编译器能够通过constexpr成员函数指针传递默认参数是合理的.如果这个编译器成功编译了<edit>上面的代码而没有警告</ edit>,有效地传递0, 0foo::bar它,它是否仍然符合ISO C++标准?

可接受的答案将参考标准(或其工作草案).我还没有在N4567的工作草案中找到答案.

编辑:如果标准没有对此问题发表评论,我也会接受这个问题.

c++ language-lawyer constexpr c++11

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