标签: constexpr

constexpr中使用strcmp的编译器差异

以下在GCC中编译,但在Clang中不编译:

#include <cstring>

constexpr int test = strcmp("test", "test");
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,GCC如何以不同的方式处理strcmp才能做到这一点?是strcmp是某种内置类型,还是标准库具有包含constexpr的非标准strcmp定义?

c++ gcc clang constexpr c++11

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

使用lambda捕获的constexpr值作为数组维度

GCCClang编译以下代码:

void Test()
{
   constexpr int Size = 3;
   auto Lambda = [Size]{ int Dim[Size]; };
}
Run Code Online (Sandbox Code Playgroud)

但是,VisualStudio 2015 CTP 6没有.尽管如此,所有3个编译器都对此代码感到满意:

void Test()
{
   static constexpr int Size = 3;
   auto Lambda = []{ int Dim[Size]; };
}
Run Code Online (Sandbox Code Playgroud)

哪个片段实际上是以正确的方式进行的?C++标准说什么?

这个问题与Lambda捕获constexpr对象有关

arrays lambda constexpr c++11 c++14

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

如何标记constexpr函数的参数未使用?

考虑这个经典的例子:

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&array)[N]) noexcept { return N; }
Run Code Online (Sandbox Code Playgroud)

现在这个工作正常,但有一个烦恼,gcc发出警告:

warning: unused parameter ‘array’ [-Wunused-parameter]
Run Code Online (Sandbox Code Playgroud)

已知解决方案:

  • 不起作用:如果我将经典添加(void)arr;到函数中,我会得到error: body of constexpr function ‘...‘ not a return-statement.
  • 不满意:我可以arraySize(T (&)[N]),但我想说出这个论点有两个原因:
    1. 它使编译器错误消息更容易理解.
    2. 更主观地说,我认为它使代码更清晰,特别是那些没有生活和呼吸语法的人.
  • 不好:在这个特殊的例子中,我也可以return sizeof(array)/sizeof(array[0]);,但这种方法不是通用的解决方案,而且我认为return N;更好,绝对更容易.
  • 好但不总是可能:切换到使用C++ 14和完全支持它的编译器.然后{ (void)array; return N; }允许constexpr函数体.

在使用C++ 11时,如何很好地消除未使用的参数警告

c++ constexpr c++11

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

在常量表达式中更改联合的活动成员

constexprunion我一起玩,我发现我不能更改unionin的活动成员constexpr。唯一的例外:union空类。

constexpr bool t()
{
    struct A {};
    struct B {};
    union U { A a; B b; } u{};
    u.a = A{};
    u.b = B{};
    return true;
}
static_assert(t());

constexpr bool f()
{
    struct A { char c; };
    struct B { char c; };
    union U { A a; B b; } u{};
    u.a = A{};
    u.b = B{}; // error originating from here
    return true;
}
static_assert(f());
Run Code Online (Sandbox Code Playgroud)

第一个函数可能会产生常量表达式。但是第二个不能。硬错误说: …

c++ variant unions constexpr c++14

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

拥有constexpr静态字符串会产生链接器错误

以下程序给出了链接时错误:

#include <iostream>

struct Test { static constexpr char text[] = "Text"; };

int main()
{
    std::cout << Test::text << std::endl; // error: undefined reference to `Test::text'
}
Run Code Online (Sandbox Code Playgroud)

错误消息是

/tmp/main-35f287.o: In function `main':
main.cpp:(.text+0x4): undefined reference to `Test::text'
main.cpp:(.text+0x13): undefined reference to `Test::text'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

好.让我们试着解决这个问题:我在struct体外添加一个定义:

#include <iostream>

struct Test { static constexpr char text[] = "Text"; };
constexpr char Test::text[] = "Text";

int main()
{ …
Run Code Online (Sandbox Code Playgroud)

c++ string type-traits constexpr c++11

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

在`static_assert`,`if constexpr(...)`和`constexpr`变量之间的模板中对`constexpr` lambdas的评估不一致

(使用g++ 7.0trunk.)

鉴于以下"类型到价值包装"实用程序......

template <typename T>
struct type_wrapper { using type = T; };

// "Wraps" a type into a `constexpr` value.
template <typename T>
constexpr type_wrapper<T> type_c{};
Run Code Online (Sandbox Code Playgroud)

...我创建了以下函数来检查表达式的有效性:

template <typename TF>
constexpr auto is_valid(TF)
{
    return [](auto... ts) constexpr 
    {
        return std::is_callable<TF(typename decltype(ts)::type...)>{};
    };
}   
Run Code Online (Sandbox Code Playgroud)

is_valid功能可以使用如下:

// Evaluates to `true` if `some_A.hello()` is a valid expression.
constexpr auto can_add_int_and_float = 
    is_valid([](auto _0) constexpr -> decltype(_0.hello()){})
        (type_c<A>);

// Evaluates to `true` if `some_int + some_float` is …
Run Code Online (Sandbox Code Playgroud)

c++ lambda constant-expression constexpr c++17

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

为什么GCC在编译时不评估constexpr?

举个例子:

class something {
public:
  static constexpr int seconds(int hour, int min, int sec)
  { return hour*3600+min*60+sec; }
}
Run Code Online (Sandbox Code Playgroud)

然后:

printf("Look at the time: %d\n", something::seconds(10, 0, 0));
Run Code Online (Sandbox Code Playgroud)

将编译为使用g ++调用函数,而不是使用常数.为什么g ++会这样做?它没有任何好处,有点挫败了使用constexpr而不是糟糕的宏的目的.

c++ gcc constexpr c++11

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

对shared_ptr中的const int的未定义引用

我有一个Config课程

// config.hpp

class Config {
  public:
    static constexpr int a = 1;
    static constexpr int b = 1;
}
Run Code Online (Sandbox Code Playgroud)

并包含在main.cpp中

// main.cpp
#include "config.hpp"
int main () {
  std::cout << Config::a << std::endl; // this is ok
  std::shared_ptr<otherClass> stream = std::make_shared<otherClass>( 
Config::a); // compile error
}
Run Code Online (Sandbox Code Playgroud)

和编译器说 undefined reference to Config::a

它在使用时起作用cout,但在shared_ptr构造函数中不起作用.

我不知道为什么会这样.

c++ definition one-definition-rule constexpr c++17

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

在C++中列出<Char>类型的constexpr字符串

我试图cons-cell用C++中的函数式编程语言模拟列表结构constexpr.我有一种pair类型,一开始.这是两个不同的东西的持有者,但也支持嵌套对.这是代码.

template <typename E1, typename E2>
struct pair {

    constexpr pair() 
    :_car{E1{}}, _cdr{E2{}}
    {}

    constexpr pair(const E1 &car, const E2 &cdr)
    :_car{car}, _cdr{cdr}
    {}

    constexpr auto car() const{
        return _car;
    }

    constexpr auto cdr() const{
        return _cdr;
    }

    friend std::ostream& operator<<(std::ostream& str,
                                    pair<E1, E2> p){
        if(p == pair{})
            return str;
        str << p.car() << " " << p.cdr();
        return str;
    }

    template <typename Functor>
    friend constexpr auto fmap(Functor f,
                               const pair<E1, E2> p){
        if …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr

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

第一个模板类型的模板参数

我正在使用一个API,它将带有单个参数的函数作为回调.回调采用某种类型的单个参数,为简单起见,我会说它返回一个bool.我试图整理的主要内容是范围检查功能.我的直觉是写这样的东西:

template<class T, T min, T max>
constexpr bool in_range(T val) {
    return (val >= min && val <= max);
}

static_assert(in_range<float, 0.0f, 1.0f>(0.5f), "doesn't work")
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,所以我默认以这种方式创建一个函数.

template<class T>
std::function<bool(T)> in_range(T min, T max) {
    auto test = [min, max](T val) {
        return (val >= min && val <= max);
    };
    return test;
}


assert(in_range<float>(0.0f, 1.0f)(0.5f))
Run Code Online (Sandbox Code Playgroud)

有没有办法以第一个函数的形式更多地编写函数,所以我不依赖std::function于运行时生成的lambdas?

c++ templates callback constexpr c++11

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