标签: constexpr

表达式不是一个整体常量clang libc ++ threading

我正在尝试在我的linux机器(ubuntu)上编译一个非常简单的线程程序,但是即使我指定了libc ++,clang似乎仍然会向我抛出错误.我的计划是:

#include <iostream>
#include <thread>

void call_from_thread() {
    std::cout << "Hello, World!" << std::endl;
}

int main()
{
    std::thread t1(call_from_thread);

    t1.join();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

生成文件:

CC=clang++
CFLAGS=-std=c++11 -stdlib=libc++ -pthread -c -Wall
#proper declaration of libc++, but still an error...
LDFALGS=
SOURCES=main.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=bimap

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
        $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
        $(CC) $(CFLAGS) $< -o $@
Run Code Online (Sandbox Code Playgroud)

具体错误:

In file included from main.cpp:2:
In file included from /usr/include/c++/4.6/thread:37:
/usr/include/c++/4.6/chrono:666:7: error: static_assert expression is not an
      integral constant …
Run Code Online (Sandbox Code Playgroud)

c++ makefile clang constexpr c++11

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

非类型模板参数不是常量表达式

我有以下代码:

#include <cstdlib>
#include <cstdio>
#include <atomic>

enum ATYPE { Undefined = 0, typeA, typeB, typeC };

template<ATYPE TYPE = Undefined>
struct Object
{
    Object() { counter++; }
    static std::atomic<int> counter;
};

template<ATYPE TYPE>
std::atomic<int> Object<TYPE>::counter(1);

template<ATYPE TYPE>
void test()
{
    printf("in test\n");
    Object<TYPE> o;
}

int main(int argc, char **argv)
{
    test<typeA>();
    printf("%d\n", Object<typeA>::counter.load());
    Object<typeA>::counter.store(0);
    for (int i = 0; i < sizeof(ATYPE); ++i) {
        Object<static_cast<ATYPE>(i)>::counter.store(0);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我使用以下命令行编译时:

clang++ -o test -std=c++11 -stdlib=libc++ test.cpp
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

test.cpp:32:20: …
Run Code Online (Sandbox Code Playgroud)

c++ templates constexpr c++11 clang++

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

G ++ vs Clang:constexpr和const的行为不一致

请考虑以下代码:

constexpr const int A = 42;

const int &B = A;
static_assert(&A == &B, "Bug");

constexpr const int &C = B;
static_assert(&A == &C, "Bug");

int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)

它完全被clang 3.3版所接受,而g ++(SUSE Linux)4.8.1 20130909 [gcc-4_8-branch revision 202388拒绝它:

bug2.cpp:5:1: error: non-constant condition for static assertion
 static_assert(&A == &B, "Bug");
 ^
bug2.cpp:5:1: error: the value of ‘B’ is not usable in a constant expression
bug2.cpp:2:12: note: ‘B’ was not declared ‘constexpr’
 const int &B = A;
            ^
Run Code Online (Sandbox Code Playgroud)

在我看来,海湾合作委员会是正确的(而我当然更喜欢铿锵行为).试图阅读标准我意识到我不够语言律师来决定.任何人都可以证实吗?

c++ static-assert language-lawyer constexpr c++11

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

我对下面的断言是对的吗?

在他的新书"TCPL"的第10.4.3节中,B.Stroustrup写道:

可以在常量表达式中使用足够简单的用户定义类型.例如:

struct Point {
    int x,y,z;
    constexpr Point up(int d) { return {x,y,z+d}; }
    constexpr Point move(int dx, int dy) { return {x+dx,y+dy}; }
// ...
};
Run Code Online (Sandbox Code Playgroud)

具有constexpr构造函数的类称为文字类型.为了简单到constexpr,构造函数必须有一个空体,所有成员必须由可能的常量表达式初始化.例如:

constexpr Point origo {0,0};

由于以下原因,这似乎让我感到困惑:

  • struct Point 没有用户定义的构造函数,它的隐式默认构造函数也不是constexpr.
  • constexpr Point origo {0,0};由于标准(N3337)第7.1.5/9段关于使用constexpr对象声明和第8.5.1/7段有关汇总初始化的汇编而编制.它与constexpr构造函数无关.

c++ initialization constexpr c++11

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

C++ 1y/C++ 14:将静态constexpr数组转换为非类型模板参数包?

假设我有一个静态存储持续时间的constexpr数组(已知绑定):

constexpr T input[] = /* ... */;
Run Code Online (Sandbox Code Playgroud)

我有一个需要包的输出类模板:

template<T...> struct output_template;
Run Code Online (Sandbox Code Playgroud)

我想实例化output_template如下:

using output = output_template<input[0], input[1], ..., input[n-1]>;
Run Code Online (Sandbox Code Playgroud)

一种方法是:

template<size_t n, const T (&a)[n]>
struct make_output_template
{
    template<size_t... i> static constexpr
    output_template<a[i]...> f(std::index_sequence<i...>)
    { return {}; };

    using type = decltype(f(std::make_index_sequence<n>()));
};

using output = make_output_template<std::extent_v<decltype(input)>, input>::type;
Run Code Online (Sandbox Code Playgroud)

我缺少更清洁或更简单的解决方案吗?

c++ templates variadic-templates constexpr c++14

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

C++ 11 constexpr函数中的常量表达式字符串参数

我正在尝试创建一个constexpr将UUID字符串转换为类似"f6ece560-cc3b-459a-87f1-22331582216e"这样的类的函数:

class UUID {
public:
      explicit UUID(uint8_t bytes[]); // Must be 16 byte array.
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所得到的:

// Compile time hex conversion of a single character into a nibble (half-byte).
constexpr uint8_t hexToNibble(char a)
{
    // Does not work:
//  static_assert(a >= '0' && a <= '9' || a >= 'a' && a <= 'f' || a >= 'A' && a <= 'F', "Invalid hex character");
    return a >= '0' && a <= '9' ? (a - '0') …
Run Code Online (Sandbox Code Playgroud)

constexpr c++11

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

如何定义constexpr变量

我想使用一个简单的编译时常量,例如:

double foo(double x) { return x + kConstDouble; }
Run Code Online (Sandbox Code Playgroud)

现在我至少看到以下定义该常量的方法

namespace { static constexpr double kConstDouble = 5.0; }
namespace { constexpr double kConstDouble = 5.0; }
static constexpr double kConstDouble = 5.0;
constexpr double kConstDouble = 5.0;
Run Code Online (Sandbox Code Playgroud)

哪种方式正确?kConstDouble在标题与源文件中定义时是否存在差异?

constexpr c++11

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

参数仅用于constexpr函数体内未评估的上下文中

下面的代码已成功使用gcc 5.3.0编译,但无法使用clang 3.7.0进行编译.在两种情况下,我都使用相同命令行选项的在线coliru编译器:-std = c ++ 14 -O2 -Wall -pedantic -pthread.

#include <cstdio>

// Definition of constexpr function 'foo'.
constexpr std::size_t foo(const int& arg_foo) { return sizeof(arg_foo); }

// Definition of function 'test'.
void test(const int& arg)
{ 
  // The following line produces an error with clang.
  constexpr std::size_t res_foo = foo(arg);

  // Print the result returned by the 'foo' function.
  std::printf("res_foo = %lu\n", res_foo);
}

// Definition of function 'main'.
int main(int argc, const char* argv[])
{
  // Test …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++14

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

Constexpr隐式声明了函数

对于类型为T的类,编译器可以生成以下成员,具体取决于类:

  • 默认构造函数: T::T()
  • 复制构造函数: T::T(const T&)
  • 移动构造函数: T::T(T&&)
  • 复制赋值运算符: T& T::operator=(const T&)
  • 移动赋值运算符: T& T::operator=(T&&)

在C++ 14和C++ 17中,哪些规则导致constexpr编译器生成这些函数的版本?

constructor assignment-operator constexpr c++14 c++17

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

C ++ constexpr重载,用于编译时和运行时的不同代码

constexpr void X() {
  /* code, that can be executed at compiletime */
}

void X() {
  /* code, that does the same as above, but is optimized for runtime, eg.
  including caching, assembler code, ... to optimize runtime performance */
}
Run Code Online (Sandbox Code Playgroud)

如上所示,我想要两个函数,它们基本上都在做相同的事情,一个针对运行时进行了优化,一个针对编译时进行了优化。在我的示例中,运行时版本涉及缓存,这不能在constexpr中完成,但可以提高运行时的性能。

可以通过某种方式(使用C ++ 14)实现吗?

如果只能使用特定于编译器的解决方案来实现此目的,那么它们也可以,但是我更喜欢一种标准解决方案(当前,我不知道有一个解决方案)

c++ optimization constexpr c++14

5
推荐指数
0
解决办法
78
查看次数