标签: constexpr

constexpr问题,为什么这两个不同的程序用g ++在这么不同的时间内运行?

我正在使用gcc 4.6.1并且正在获得一些涉及调用constexpr函数的有趣行为.这个程序运行得很好,直接打印出来12200160415121876738.

#include <iostream>

extern const unsigned long joe;

constexpr unsigned long fib(unsigned long int x)
{
   return (x <= 1) ? 1 : (fib(x - 1) + fib(x - 2));
}

const unsigned long joe = fib(92);

int main()
{
   ::std::cout << "Here I am!\n";
   ::std::cout << joe << '\n';
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个程序需要永远运行,我从来没有耐心等待它打印出一个值:

#include <iostream>

constexpr unsigned long fib(unsigned long int x)
{
   return (x <= 1) ? 1 : (fib(x - 1) + …
Run Code Online (Sandbox Code Playgroud)

c++ g++ constexpr c++11

11
推荐指数
1
解决办法
796
查看次数

constexpr变量的唯一地址

是否可以为constexpr变量分配唯一的地址,即对于变量可用的所有翻译单元(通常通过标题)都是相同的?请考虑以下示例:

// foo.hh
#include <iostream>
constexpr int foo = 42;

// a.cc
#include "foo.hh"
void a(void) { std::cout << "a: " << &foo << std::endl; }

// b.cc
#include "foo.hh"
extern void a(void);
int main(int argc, char** argv) {
  a();
  std::cout << "b: " << &foo << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

使用gcc 4.7 编译a.ccb.cc分开并将它们链接在一起,我看到打印了两个不同的地址.如果我extern在标题中添加关键字,我会收到链接器错误duplicate symbol _foo in: a.o and b.o,我觉得有点令人惊讶,因为我认为添加extern更有可能导致编译器从另一个对象导入该符号,而不是从当前对象导出它.但似乎我对这些事情的运作方式的理解是错误的.

是否有合理的方法在一个标题中声明constexpr,这样所有翻译单元都可以在其常量表达式中使用它,并且所有翻译单元都同意该符号的地址?我希望一些额外的代码来表示这个符号实际所属的单个翻译单元,就像没有的externextern变量一样constexpr.

c++ extern memory-address constexpr c++11

11
推荐指数
2
解决办法
3429
查看次数

为什么标准库常见的数学函数不是"常量表达式"?

出于某种原因,clang ++(但不是g ++)抱怨:

constexpr double invdecayf1m(double x) {
  return -log1p(-x);
}
Run Code Online (Sandbox Code Playgroud)

告诉我

non-constexpr function 'log1p' cannot be used in a constant expression
  return -log1p(-x);
Run Code Online (Sandbox Code Playgroud)

为什么在所有声明的常用数学函数<cmath>都不是" constexpr函数"

cmath constexpr c++11

11
推荐指数
1
解决办法
370
查看次数

C++ 11 constexpr函数传递参数

请考虑以下代码:

static constexpr int make_const(const int i){
    return i;
}

void t1(const int i)
{
    constexpr int ii = make_const(i);  // error occurs here (i is not a constant expression)
    std::cout<<ii;
}

int main()
{
   t1(12);
}
Run Code Online (Sandbox Code Playgroud)

为什么我在make_const调用时出错?


UPDATE

但是这个有效:

constexpr int t1(const int i)
{
    return make_const(i);
}
Run Code Online (Sandbox Code Playgroud)

但是,这不是:

template<int i>
constexpr bool do_something(){
    return i;
}

constexpr int t1(const int i)
{
    return do_something<make_const(i)>();   // error occurs here (i is not a constant expression)
}
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

11
推荐指数
2
解决办法
1万
查看次数

constexpr-function参数如果直接使用则被认为是constexpr,但如果用于调用另一个constexpr函数则不被认为是constexpr

在尝试使用constexpr函数和模板(以及非类型模板参数)时,我偶然发现了一个现象,我无法理解哪个规则使它生效.

因此,根据有关constexpr-s的规则,我的问题基本上是"为什么会发生这种情况"."这个"如下.

在其中一个constexpr函数中,如果直接使用参数,则在编译时计算中使用此参数没有问题.(示例第2行)

当相同的参数用作另一个constexpr函数的参数时,编译器会抱怨此表达式(参数id)不是constexpr.(例子第3行)

简而言之:

template <typename T> constexpr std::size size (T obj) { return obj.size(); }
template <typename T> constexpr auto sz1 (T obj) { return std::make_index_sequence< obj.size() > { }.size(); } // OK ...
template <typename T> constexpr auto sz2 (T obj) { return std::make_index_sequence< size(obj) > { }.size(); } // ERROR
  // "obj" is [suddenly] not a constexpr
Run Code Online (Sandbox Code Playgroud)

g ++ - 4.9.1和clang ++ - 3.4.2都会发生这种情况.

下面是一个小型测试程序,用于快速简便的实验.


#include <utility>
#include <array>
#include <iostream>

// utils
template <size_t N> …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr

11
推荐指数
2
解决办法
658
查看次数

类本身内部的静态constexpr类对象数组

是否有可能在C++中有这样的东西:

struct Foo
{
    int x;
    constexpr Foo(int x) : x(x) {}

    static constexpr Foo table[] =
    {
        Foo(0),
        Foo(1),
        Foo(2),
    };
};
Run Code Online (Sandbox Code Playgroud)

我尝试了几种组合,但都没有效果.如果table不是Foo类的一部分,它可以工作,但我真的希望它成为Foo命名空间的一部分.


编辑:

我想要这个的原因是我可以访问表格Foo::table.我在命名空间中有几个这样的类,如果我可以通过编写导入我正在使用的类using someNamespace::Foo然后访问该表,这非常方便Foo::table.如果表在课外,我必须始终通过写作来访问它someNamespace::fooTable.

c++ arrays static constexpr

11
推荐指数
2
解决办法
430
查看次数

使用constexpr函数作为参数时,enable_if无法在Visual Studio中工作

我目前正在与Visual Studio 2017进行斗争(/std:c++latest如果有任何帮助,请编译使用).

有问题的代码只是根据一些模板化constexpr函数的结果选择结构特化.GCC和clang编译它没有问题.

这是我的MCVE:

#include <type_traits>

struct A {
  enum {
    test_trait = true
   };
};

template<typename T>
constexpr int choose() {
  return T::test_trait;
}

template<typename T, typename Enable=void>
struct Chosen;

template<typename T>
struct Chosen<T, std::enable_if_t<choose<T>() == 1>> {};

void foo() {
  // This works
  constexpr int chosen = choose<A>();
  static_assert(chosen == 1, "");

  // This resolves to the undefined struct.
  using Chosen_t = Chosen<A>;
  Chosen_t x;
  (void)x;
}
Run Code Online (Sandbox Code Playgroud)

choose()在我的代码库中实际上有点复杂,但static_assert仍然编译,并检查正常.

我有点假设,如果static_assert …

c++ visual-studio enable-if constexpr c++14

11
推荐指数
1
解决办法
335
查看次数

从一些字符串文字和一个int模板参数的连接中创建一个constexpr C字符串

我有一个带有int模板参数的类.在某些情况下,我希望它输出一条错误消息.此消息应该是来自某些固定文本和模板参数的串联字符串.出于性能原因,我希望每次发生错误时都避免在运行时构建此字符串,理论上两者都是,字符串文字和模板参数在编译时是已知的.所以我正在寻找将其声明为constexpr的可能性.

代码示例:

template<int size>
class MyClass
{
    void onError()
    {
        // obviously won't work but expressing the concatenation like
        // it would be done with a std::string for clarification 
        constexpr char errMsg[] = "Error in MyClass of size " + std::to_string (size) + ": Detailed error description\n";

        outputErrorMessage (errMsg);
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ string constexpr

11
推荐指数
1
解决办法
492
查看次数

使用constexpr函数作为模板参数是否有效?

constexpr int get () { return 5; }
template<int N> struct Test {};

int main ()
{
  int a[get()];  // ok
  Test< get() > obj;  // error:'int get()' cannot appear in a constant-expression
}
Run Code Online (Sandbox Code Playgroud)

用ideone编译了这段代码.并且想知道为什么它会给出编译错误.是constexpr不允许函数作为template参数,还是编译器中的错误?

编辑:更改const int get()int get() 此外,还有一个与ideone的错误是,如果你删除constexpr然后仍然声明一个数组是允许的!我认为这是一个C99功能.

c++ templates compiler-errors constexpr c++11

10
推荐指数
1
解决办法
1467
查看次数

有替换X-macros的模板/ constexpr/C++ 11方法吗?

有没有办法用C++ 11功能替换Xmacro习语,最好不要使用预处理器?我认为可以使用元组模板,但我仍然试图弄清楚这些是如何工作的.

c++ templates constexpr c++11

10
推荐指数
1
解决办法
614
查看次数