I'm delving into address constant expressions while reading "C++ Programming Language 4th edition" book. It has a short paragraph which describes address constant expressions:
The address of a statically allocated object, such as a global variable, is a constant. However, its value is assigned by the linker, rather than the compiler, so the compiler cannot know the value of such an address constant. That limits the range of constant expressions of pointer and reference type. For example:
Run Code Online (Sandbox Code Playgroud)constexpr const char* …
我正在尝试使用 C++11 新的 constexpr 功能在编译时评估这个简单的表达式:
template <int a, int b>
class Test
{
static constexpr double c = a / b;
};
Run Code Online (Sandbox Code Playgroud)
但这是 Clang 一直告诉我的:
Constexpr variable 'c' must be initialized by a constant expression
Run Code Online (Sandbox Code Playgroud)
奇怪的是,以下编译得很好:
template <int a, int b>
class Test
{
static constexpr double c = a / 2.f;
};
Run Code Online (Sandbox Code Playgroud)
你们知道为什么 a/b 不是常量表达式,我怎么能在编译时评估它?
使用带有 -std=c++1y 和 -stdlib=libc++ 的 Clang 编译器
更新
以下示例导致原始代码出现错误:
Test<10,0> test1 ;
Run Code Online (Sandbox Code Playgroud)
尽管:
Test<10,1> test1 ;
Run Code Online (Sandbox Code Playgroud)
才不是。
我有以下代码
constexpr int into(int a,int b)
{
int c=a*b;
return c;
}
int main()
{
constexpr int &n=into(5,5);
}
Run Code Online (Sandbox Code Playgroud)
我已阅读(在MSDN中)
该关键字
constexpr是在C++ 11中引入的,并在C++ 14中进行了改进.这意味着不断表达.例如const,它可以应用于变量,以便在任何代码尝试修改该值时引发编译器错误.
在我阅读之后,我认为constexpr可以代替使用const,但对于上面的代码我得到一个编译器错误说明
Run Code Online (Sandbox Code Playgroud)`int main()': invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'`
什么时候constexpr更换const,它工作正常.我不明白这种行为; 有人可以解释一下吗?
我正在尝试使 constexpr 一些现有代码,但收到消息
错误:“my_string”在“constexpr”函数中声明为“static”
简化了很多,代码如下:
template <typename T>
constexpr
int foo(const int x)
{
static // error: 'my_string' declared 'static' in 'constexpr' function
constexpr char my_string[] = "my foo error message!";
if (x == 0)
{
std::cout << my_string << std::endl;
}
return x;
}
class boo
{
public:
constexpr boo()
{
static // error: 'constructor_string' declared 'static' in 'constexpr' function
constexpr char constructor_string[] = "my constructor error message.";
}
};
Run Code Online (Sandbox Code Playgroud)
字符串当然在其他地方使用,我想确保它们永远不会重复(如此静态)(并且我想保持使用静态以与 C++03 兼容,其中 constexpr 不可用使用BOOST_CONSTEXPR_OR_CONST)。
这个问题是this one的后续问题。
这是关于nvcc编译器将static constexpr设备代码中的类变量识别为未定义的,如果该变量是 odr 使用的。但是,我找不到原因,为什么它不起作用。
错误信息是:
error: identifier "Tester<int> ::ONE" is undefined in device code
Run Code Online (Sandbox Code Playgroud)
编译与
nvcc -std=c++11 -ccbin=/usr/bin/g++-4.9 -arch=sm_30 main.cu
Run Code Online (Sandbox Code Playgroud)
该nvcc编译器版本release 8.0, V8.0.26。
一个最小的例子(上一个问题中的 MWE 的缩短版本,专注于这个特定问题)由
#include <iostream>
#include <cstdlib>
#ifdef __CUDACC__
#define HD __host__ __device__
#else
#define HD
#endif
HD void doSomething(const int& var ) {};
template<typename T> class Tester
{
public:
static constexpr int ONE = 1;
HD void test()
{
doSomething( ONE );
}
}; …Run Code Online (Sandbox Code Playgroud) 我开始尝试constexpr.
我想要实现的是验证literal作为ctor参数提供的数值.
我开始使用以下内容,如果构造MyStruct
值<= 4 则抛出.
constexpr int validate(int v)
{
return (v > 4) ? v : throw exception();
};
struct MyStruct final
{
constexpr MyStruct(const int v)
: _v{validate(v)}
{
}
void add(int toAdd)
{
_v += toAdd;
}
int _v;
};
int main(int argc, char**)
{
constexpr MyStruct a{500}; // ok so far...
a.add(argc); // ...nope
MyStruct b{500}; // check at runtime :(
MyStruct c{argc}; // runtime check ok
}
Run Code Online (Sandbox Code Playgroud)
标记MyStruct …
考虑以下代码片段:
int main(){
constexpr int x = -1;
if(x >= 0){
constexpr int y = 1<<x;
}
}
Run Code Online (Sandbox Code Playgroud)
GCC 7(可能还有其他版本的GCC)拒绝对此进行编译,并说:
error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
我可以猜想这可能是从哪里来的:constexpron 的声明y使GCC y在编译时进行评估,而在这里它可能是负数。删除constexpr修复错误。
但是,这是标准的未定义行为吗?条件始终为假,因此y将永远不会使用的值。
在我的实际代码中,x是模板参数,该参数可以为负,也可以不为负。
正常if情况下,短路工作。
但是,如果尝试短路 if-constexpr 不起作用:
#include <iostream>
template <typename ... Args>
void foo(Args... args) {
std::string a;
// for the call of foo, sizeof...(args) = 0, so a > 2 shouldn't be evaluated.
if constexpr (sizeof...(args) == 0 || a > 2) {
std::cout << "ASD" << '\n';
}
}
int main() {
foo();
}
Run Code Online (Sandbox Code Playgroud)
编辑:似乎很多评论都与我的尝试有所不同。我将引用@chris 的评论:
人们似乎没有抓住重点,所以这里有一个更好的例子来说明为什么这很有用:
Run Code Online (Sandbox Code Playgroud)if constexpr (sizeof...(Ts) > 0 && is_integral_v<first_t<Ts...>>) { /* corresponding logic */ }目前,这需要嵌套的 constexpr ifs
这似乎目前是不可能的,唯一的解决方法是编写嵌套的 ifs。
让我们假设我想写一个结构体,它有一个成员 constexpr std::array ,它包含前 N 个 fibs,其中 N 是一个模板参数。
类似这样的东西,但 vals 在编译时可用:
template <int N>
struct first_n_fibs {
static_assert(N>0);
static const std::array<int, N> vals;
static std::array<int, N> init_fibs(){
std::array<int,N> result;
if (N==1) {
return std::array<int,N>{1};
} else {
result[0]=1;
result[1]=1;
for(int i =2; i<N;++i) {
result[i]=result[i-2]+result[i-1];
}
}
return result;
}
};
template<int N>
const std::array<int, N> first_n_fibs<N>::vals=init_fibs();
int main(){
std::cout << first_n_fibs<2>::vals.back() << std::endl;
std::cout << first_n_fibs<5>::vals.back() << std::endl;
std::cout << first_n_fibs<6>::vals.back() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我怀疑没有解决方法,因为 std::array 构造函数不是 constexpr,所以如果有人知道任何涉及 …
我试图用 constexpr 变量和 ifs 替换我用来控制条件编译的预处理器 #define 和 #if/#ifdef。
是否可以声明 constexpr 变量,以便它们重现 #defines,因为它们不分配运行时存储空间,并且采用 1 的地址会导致编译时错误?
所以在标题中我想有类似的东西
namespace ExampleNamespace
{
enum class Platform : int {Darwin, Linux, Windows};
constexpr Platform BuildPlatform = Platform::Darwin; // Line A.
};
Run Code Online (Sandbox Code Playgroud)
在我想要的代码中
if constexpr (Platform::Darwin == BuildPlatform) // Line B.
{
cout << "Platform is Darwin" << endl;
}
else
{
cout << "Platform is not Darwin" << endl;
};
const Platform *const PlatformAddress = &BuildPlatform; // Line C.
const Platform &BuildPlatform2 = BuildPlatform; // …Run Code Online (Sandbox Code Playgroud)