标签: constexpr

用户定义的文字参数不是constexpr?

我正在测试用户定义的文字.我想让_fac返回数字的阶乘.

让它调用一个constexpr函数是有效的,但它不允许我用模板做,因为编译器抱怨参数不是也不可能constexpr.

我对此感到困惑 - 不是文字常量表达式吗?该55_fac始终是一个文字,可以在编译时计算,所以为什么我不能用它作为这样?

第一种方法:

constexpr int factorial_function(int x) {
  return (x > 0) ? x * factorial_function(x - 1) : 1;
}

constexpr int operator "" _fac(unsigned long long x) {
  return factorial_function(x); // this works
}
Run Code Online (Sandbox Code Playgroud)

第二种方法:

template <int N> struct factorial_template {
  static const unsigned int value = N * factorial_template<N - 1>::value;
};
template <> struct factorial_template<0> {
  static const unsigned int value = 1; …
Run Code Online (Sandbox Code Playgroud)

c++ user-defined-literals constexpr c++11

23
推荐指数
2
解决办法
3908
查看次数

为什么std :: tie没有标记为c ++ 14的constexpr?

这是我之前提出的问题的后续问题"C++ 14标准库的哪些部分可能是什么以及将制作哪些部分constexpr?" " constexpr运营商超载指南?"

在运行时世界中,为多个数据成员的结构重载的operator<一个很好的习惯用法std::tie将结构转换为a std::tuple并在其上进行捎带,operator<这就是Right Thing™(各种成员的字典比较).

在C++ 14,许多地方std::tuple制成constexpr,特别是make_tuple,std::get与前面提到的operator<.然而,似乎看似相关std::tie的没有标记constexpr.这很烦人,因为它使定义用户定义的文字类型在编译时可以比必要的更冗长.

问题:是否有任何技术原因std::tie未标记constexpr为C++ 14?

更新:LWG问题2301,在libc ++libstdc ++ bug 65978中实现

更新2:在修改libstdc ++错误报告后,由@JonathanWakely修复了3个多小时!

c++ tuples constexpr c++11 c++14

23
推荐指数
1
解决办法
1279
查看次数

可以从三元运算符抛出异常吗?

有时候只需要一个语句(返回时就必须这样)是方便的,甚至是必要的constexpr.如果需要检查条件并且只允许一个语句,则条件运算符是唯一的选项.如果出现错误,最好从条件运算符中抛出异常,例如:

template <typename It>
typename std::iterator_traits<It>::reference
access(It it, It end) {
    return it == end? throw std::runtime_error("no element"): *it;
}
Run Code Online (Sandbox Code Playgroud)

但是,当用作例如(实例)时,上述函数不会编译:

std::vector<int> v;
access(v.begin(), v.end());
Run Code Online (Sandbox Code Playgroud)

编译器抱怨尝试将非const引用绑定到临时.不过,编译器并没有抱怨throw-expression本身.所以问题是:可以从条件运算符抛出异常,如果是这样,上面的代码出了什么问题?

c++ constexpr c++11

23
推荐指数
3
解决办法
1456
查看次数

为什么必须在运行时构造字符串?

可以在运行时创建C-Strings还是std::string必须创建constexpr它们?

使用gcc 4.9.2我可以这样做:

constexpr const char foo[] = "blee";
Run Code Online (Sandbox Code Playgroud)

(遗憾的是,2013年11月的客户技术预览版不允许Visual Studio支持此功能:https://stackoverflow.com/a/29255013/2642059)

但即使使用gcc 4.9.2我也不能这样做:

constexpr const std::string foo = "blee";
Run Code Online (Sandbox Code Playgroud)

我收到错误:

error: the type 'const string {aka const std::basic_string<char>}' of constexpr variable 'foo' 
       is not literal

 constexpr const std::string foo = "blee";
                                   ^
note: 'std::basic_string<char>' is not literal because:
     class basic_string
           ^
note:   'std::basic_string<char>' has a non-trivial destructor
Run Code Online (Sandbox Code Playgroud)

但我想更多地澄清为什么 a std::string不是文字.也就是说:为什么必须在运行时构造字符串?

正如所指出的,这个问题可以部分回答:是否可以在constexpr中使用std :: string?但它没有涉及为什么std::string不能成为问题核心的文字.

c++ literals stdstring constexpr c++11

23
推荐指数
2
解决办法
2092
查看次数

在常量表达式中调用的`static constexpr`函数是......错误?

我有以下代码:

class MyClass
{
  static constexpr bool foo() { return true; }
  void bar() noexcept(foo()) { }    
};
Run Code Online (Sandbox Code Playgroud)

我希望,因为它foo()是一个static constexpr函数,并且因为它是在bar声明之前定义的,所以这是完全可以接受的.

但是,g++给我以下错误:

 error: ‘static constexpr bool MyClass::foo()’ called in a constant expression
Run Code Online (Sandbox Code Playgroud)

这是......不太有用,因为在常量表达式中调用函数的能力是整个点constexpr.

clang++更有帮助.除了声明参数noexcept必须是常量表达式的错误消息之外,它还说:

note: undefined function 'foo' cannot be used in a constant expression
note: declared here
static constexpr bool foo() { return true; }
                      ^
Run Code Online (Sandbox Code Playgroud)

那么......这是一个两遍编译问题吗?问题是编译器在定义任何成员函数之前是否尝试声明它们中的所有成员函数?(注意,在类的上下文之外,编译器都不会抛出错误.)这让我感到惊讶; 直观地说,我认为static constexpr成员函数不能在任何和所有常量表达式中使用,无论是在类中还是在类中.

c++ constant-expression noexcept constexpr c++11

23
推荐指数
1
解决办法
3474
查看次数

在constexpr函数内变换int

我为什么这样做:

constexpr auto i_can() {
   int a = 8;
   a = 9;
   //...
}
Run Code Online (Sandbox Code Playgroud)

但我不能这样做:

constexpr auto i_cannot() {
    std::array<int, 10> arr{};
    //I cannot
    arr[5] = 9;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 如果我可以改变一个int,为什么我不能改变int数组内部的那个?
  2. 这是语言限制(C++ 14)还是标准库规范问题?reference std::array<T, N>::operator[](size_t)目前不是constexpr.

c++ constexpr c++14

23
推荐指数
2
解决办法
970
查看次数

局部变量的地址是constexpr吗?

在Bjarne Stroustrup的书“ C ++编程语言(第4版)”中,第110页。267(第10.4.5节“地址常量表达式”)中,他使用了一个代码示例,其中将局部变量的地址设置为constexpr变量。我以为这看起来很奇怪,所以我尝试使用g ++ 7.3.0版运行示例,但无法获得相同的结果。这是他的逐字代码示例(尽管略有删节):

extern char glob;

void f(char loc) {
    constexpr const char* p0 = &glob; // OK: &glob's is a constant
    constexpr const char* p2 = &loc;  // OK: &loc is constant in its scope
}
Run Code Online (Sandbox Code Playgroud)

运行此命令时,我得到:

error: ‘(const char*)(& loc)’ is not a constant expression
Run Code Online (Sandbox Code Playgroud)

g ++发生了我不知道的事情,还是Bjarne的示例有更多事情?

c++ memory-address constexpr c++11

23
推荐指数
2
解决办法
914
查看次数

'const' 限定符何时保证变量是常量表达式?

据我所知,constC++中的限定符基本上声明了内部链接,有时它允许将变量用作常量表达式,以便将其放入数组边界、切换案例等。

但显然情况并非总是如此,我对const和的正确用法一无所知constexpr

具体来说,我发现当在数组边界中使用 const 限定数组的元素时,它不会被视为常量表达式,如下面的代码所示。

const int N = 3;
int foo[N] = {1, 2, 3};  // Valid

const int bar[5] = {1, 2, 3, 4, 5};
int arr[bar[2]] = {1, 2, 3};  // Invalid because a VLA can't be initialized
Run Code Online (Sandbox Code Playgroud)

在后面的部分使用constexpr而不是const解决问题。但是为什么最后一条语句无效呢?究竟需要什么才能使表达式保持不变?

c++ constant-expression constexpr

23
推荐指数
1
解决办法
1144
查看次数

如何使C++ ADL查看模板的所有实例?

我正在关注如何在C++教程中实现一个常量表达式计数器我正在尝试修复C++ 14没有宏的反射,标记或外部工具..谈话限制.

本教程的基本思想是:

template<int N>
struct flag {
  friend constexpr int adl_flag (flag<N>);
};

template<int N>
struct writer {
   friend constexpr int adl_flag (flag<N>) { return N; }
   static constexpr int value = N;
};

template<int N, class = char[noexcept(adl_flag(flag<N> ()))?+1:-1]>
int constexpr reader (int, flag<N>) { return N; }

template<int N>
int constexpr reader (float, flag<N>, int R = reader (0, flag<N-1>())) { return R; }

int constexpr reader (float, flag<0>) { return …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming constexpr c++11 c++14

22
推荐指数
1
解决办法
728
查看次数

为什么不允许在constexpr函数中转到?

C++ 14规定了constexpr函数中可以做什么和不可以做什么.其中一些(不asm,没有静态变量)似乎很合理.但该标准也不允许gotoconstexpr功能,尽管它允许其他控制流机制.
这种区别背后的原因是什么?
我以为我们过去了" goto很难编译 ".

c++ goto language-lawyer constexpr c++14

22
推荐指数
1
解决办法
892
查看次数