我正在尝试在我的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) 我有以下代码:
#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) 请考虑以下代码:
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)
在我看来,海湾合作委员会是正确的(而我当然更喜欢铿锵行为).试图阅读标准我意识到我不够语言律师来决定.任何人都可以证实吗?
在他的新书"TCPL"的第10.4.3节中,B.Stroustrup写道:
可以在常量表达式中使用足够简单的用户定义类型.例如:
Run Code Online (Sandbox Code Playgroud)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}; } // ... };具有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构造函数无关.假设我有一个静态存储持续时间的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)
我缺少更清洁或更简单的解决方案吗?
我正在尝试创建一个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) 我想使用一个简单的编译时常量,例如:
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在标题与源文件中定义时是否存在差异?
下面的代码已成功使用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) 对于类型为T的类,编译器可以生成以下成员,具体取决于类:
T::T()T::T(const T&)T::T(T&&)T& T::operator=(const T&)T& T::operator=(T&&)在C++ 14和C++ 17中,哪些规则导致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)实现吗?
如果只能使用特定于编译器的解决方案来实现此目的,那么它们也可以,但是我更喜欢一种标准解决方案(当前,我不知道有一个解决方案)