标签: constexpr

constexpr返回数组,gcc警告

我写了一个返回数组的constexpr函数.

#include <iostream>

constexpr auto get_str(void)
-> const char(&)[4] {   
    return { 'T', 'E', 'S', 'T' };
}

constexpr int sum(const char(&str)[4]){
    return str[0] + str[1] + str[2] + str[3];
}

int main(void){

    constexpr int s = sum(get_str());

    std::cout << s << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

g ++ 4.8正确编译代码,但发出以下警告:

test.cpp: In function ‘constexpr const char (& get_str())[4]’:
test.cpp:5:30: warning: returning reference to temporary [-Wreturn-local-addr]
  return { 'T', 'E', 'S', 'T' };
Run Code Online (Sandbox Code Playgroud)

在这种情况下警告是否正确?从这样的constexpr函数返回数组是不正确的,即使该函数在运行时从未实际调用过,只是在编译期间?

c++ arrays gcc gcc-warning constexpr

8
推荐指数
1
解决办法
1155
查看次数

是constexpr函数,可以在C++中加载文件吗?

这里有一个类似的问题,但它没有有价值的信息,所以我想再问一遍 - 是否可以使用constexpr函数加载任意文件的内容?我知道这似乎是不可能的,因为在这种情况下无法调用允许文件I/O(fopen,open...)的所有可能的函数constexpr.但是 - 由于这里有许多人关注c ++ 17的开发并且正在进行 - 是否有希望进一步的标准将包含一些文件I/O API,它们将constexpr在编译时用于加载文件?

仅仅为了比较--Haxe允许通过编译时宏执行几乎任何操作,因此在C++中使用类似的东西会非常酷.例如,通过反序列化文件生成类实例.

c++ constexpr

8
推荐指数
1
解决办法
1863
查看次数

为什么编译器抱怨这不是constexpr?

我正在尝试学习如何在实践中使用C++常量表达式,并创建以下Matrix类模板用于说明目的:

#include <array>

template <typename T, int numrows, int numcols>
class Matrix{
public:
    using value_type = T;
    constexpr Matrix() : {}
   ~Matrix(){}

    constexpr Matrix(const std::array<T, numrows*numcols>& a) :
        values_(a){}

    constexpr Matrix(const Matrix& other) :
        values_(other.values_){

    }

    constexpr const T& operator()(int row, int col) const {
        return values_[row*numcols+col];
    }

    T& operator()(int row, int col){
        return values_[row*numcols+col];
    }

    constexpr int rows() const {
        return numrows;
    }

    constexpr int columns() const {
        return numcols;
    }


private:
    std::array<T, numrows*numcols> values_{};
};
Run Code Online (Sandbox Code Playgroud)

我们的想法是拥有一个简单的Matrix类,我可以将它用于小矩阵,以便在编译时评估Matrix表达式(请注意,我还没有实现常用的Matrix运算符来进行加法和乘法).

当我尝试按如下方式初始化Matrix实例时:

constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ constexpr c++11

8
推荐指数
1
解决办法
1965
查看次数

constexpr log10整数函数

所以我需要一些log10功能来查找存储给定整数所需的字符数.但是我想在编译时得到它来根据我的代码中定义的这些整数常量静态地确定char数组的长度.不幸的log10是,它不是一个constexpr函数,即使是整数版本.我可以制作这样的完整版本:

template <typename T>
constexpr enable_if_t<is_integral_v<T>, size_t> intlen(T param) {
    size_t result{ 1U };

     while(T{} != (param /= T{ 10 })) ++result;
     return result;
}
Run Code Online (Sandbox Code Playgroud)

这将最终允许我这样做:const char foo[intlen(13) + 1U]
是否已经为我提供了一个工具,还是我必须自己定义?

c++ logarithm c-strings string-length constexpr

8
推荐指数
2
解决办法
476
查看次数

隐含的constexpr?

C++ 11编译器(以及他们)是否注意到一个函数是constexpr并且即使它们未被声明为constexpr也会将它们视为这样?

我正在使用维基百科中的示例向使用constexpr的人展示:

int get_five() {return 5;}

int some_value[get_five() + 7]; // Create an array of 12 integers. Ill-formed C++
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是编译器没问题.所以,我进一步更改了get_five()以获取一些int参数,将它们相乘并返回结果,同时仍未明确声明为constexpr.编译器也可以.似乎如果编译器可以做到这一点,那么为了明确声明constexpr的某些东西,没有太多的意义.

c++ constexpr c++11

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

替换常量:何时使用静态 constexpr 和内联 constexpr?

这个问题是C++17的后续问题:仍然使用枚举作为常量?.

遗留常量有多种形式,特别是:

  • #define CONSTANT x
  • enum { CONSTANT = x };
  • const /*int/unsigned/whatever*/ CONSTANT = x;

关于static constexprinline constexpr常量作为替代的评论让我想到了更新我们许多遗留常量(特别是#define常量)的主题。

据我了解,一个inline constexpr值基本上只是被替换了,就像一个内联函数(我已经被证明是错误的)。相反,一个static constexpr值作为二进制的一部分存储在一个单独的区域中。假设我理解正确,什么时候应该优先选择另一个?我的预感是,对于积分常数,inline constexpr通常是首选。

c++ constants constexpr c++17

7
推荐指数
2
解决办法
1620
查看次数

检查概念中的 constexpr

我刚开始做概念。检查表达式的语法非常有用,它为我删除了很多 sfinae 的样板文件。但是我想知道如何检查表达式是否可以在 constexpr 上下文中使用。有时这些表达式会导致无效。我可以想象的方式看起来像这样,没有注释 constexpr 关键字:

template<typename T>
concept foo = requires(T t) {
    /* constexpr */ { t.bar(); } -> std::same_as<void>;
    /* constepxr */ { T::foo; };
}
Run Code Online (Sandbox Code Playgroud)

但是,我非常怀疑这是正确的语法。有没有一种简单的方法来检查概念中表达式的constexpr-ness?

我不想检查 constexpr 函数的计算对于 的所有可能值是否不会失败t,我想知道我是否可以将该表达式放在编译器期望某些东西在编译时可评估的地方。

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

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

这应该是 constexpr 还是不?

考虑这个代码片段(Godbolt):

#include <cstdio>
#include <string>
#include <string_view>

struct Option
{
    std::string_view name;

    constexpr Option( std::string_view const n ) noexcept : name{n} {}
};

template< std::size_t N >
class TransformedOption : public Option
{
public:
    constexpr TransformedOption( std::string_view const nameStr ) :
        Option{ { nameStorage_, N - 1 } }
    {
        for ( auto i = 0U; i < N; ++i )
        {
            if ( nameStr[ i ] == '_' ) { nameStorage_[ i ] = '-'; }
            else …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++20

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

为什么 constexpr 局部变量的地址不是常量表达式?

以下 constexpr 函数无法编译:

constexpr void fnc()
{
    constexpr int i = 5;
    constexpr auto ptr = &i;
}
Run Code Online (Sandbox Code Playgroud)

ptr考虑到所有计算都发生在 constexpr 函数中并且无需声明 constexpr 即可工作,为什么不能是ptrconstexpr?

c++ constexpr kotlin

7
推荐指数
2
解决办法
548
查看次数

使用局部变量的引用来初始化 constexpr 变量是否有效?

以下代码只能在 GCC 上编译(在 godbolt.org 上检查了 10.4 和 13.2),但不能在 Clang 上编译(在我尝试过的所有版本上都失败,例如 godbolt.org 上的 17.0.1):

struct A {
  static constexpr int b{1};
};

int main(int argc, char *argv[]) { 
    A a;
    A& aref{a};
    constexpr auto bb1{a.b};
    constexpr auto bb2{aref.b};
    return bb1+bb2; 
}
Run Code Online (Sandbox Code Playgroud)

叮当输出:

struct A {
  static constexpr int b{1};
};

int main(int argc, char *argv[]) { 
    A a;
    A& aref{a};
    constexpr auto bb1{a.b};
    constexpr auto bb2{aref.b};
    return bb1+bb2; 
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/nG4j3KefE

为什么?

c++ clang language-lawyer constexpr

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