在 C++20 构造函数/函数中检测带或不带 constexpr 关键字的实例化/调用

Detecting Instantiation/Calls with or without the constexpr Keyword in C++20 Constructors/Functions

提问人:0xdeadbeef 提问时间:7/30/2023 更新时间:7/30/2023 访问量:57

问:

我目前正在尝试找到一种干净的方法来创建一个模板化的字节数组结构,该结构可以根据其构造函数是否使用constexpr关键字进行实例化,并且如果可能的话,我还想将其应用于其他方法和函数,我想知道是否有办法实现这一点?

以下是我想要实现的目标示例:

#include <iostream>
#include <cstring>

template<size_t N>
struct bytearray {
    char data[N];
    constexpr bytearray(char val) : data() {
        if constexpr (... is compile time instantiated ...) {
            for (size_t i = 0; i < N; ++i) {
                data[i] = val;
            }    
        } else {
            std::memset(data, val, N);     
        }
    }
};

int main() {
    constexpr bytearray<10> A(7);
    bytearray<10> B(7);
}

因此,在编译时实例化类将使用循环,如果不是。Aformemcpy

C++ constexpr 模板元编程 编译时类型检查

评论


答:

6赞 Artyer 7/30/2023 #1

您正在寻找 consteval

    constexpr bytearray(char val) : data() {
        if consteval {
            for (size_t i = 0; i < N; ++i) {
                data[i] = val;
            }    
        } else {
            std::memset(data, val, N);     
        }
    }

这是 C++23 的一项功能。在 C++20 中,您可以使用 std::is_constant_evaluated

    constexpr bytearray(char val) : data() {
        if (std::is_constant_evaluated()) {
            for (char& byte : data) {
                byte = val;
            }
        } else {
            std::memset(data, val, N);     
        }
    }

但请注意,在这种特定情况下,检查不是必需的。 将被编译为与任何值得其盐的编译器相同的东西。for (size_t i = 0; i < N; ++i) data[i] = val;memset