标签: constexpr

为什么const数组无法从constexpr函数访问?

我有一个名为access的constexpr函数,我想从数组中访问一个元素:

char const*const foo="foo";
char const*const bar[10]={"bar"};

constexpr int access(char const* c) { return (foo == c); }     // this is working
constexpr int access(char const* c) { return (bar[0] == c); }  // this isn't
int access(char const* c) { return (bar[0] == c); }            // this is also working
Run Code Online (Sandbox Code Playgroud)

我收到错误:

error: the value of 'al' is not usable in a constant expression
Run Code Online (Sandbox Code Playgroud)

为什么我不能从访问中访问其中一个元素?或者更好我该怎么做,如果有可能的话?

c++ constexpr c++11

3
推荐指数
1
解决办法
605
查看次数

constexpr和RTTI

我想做这样的事情:

template <typename T>
constexpr ::std::size_t type_name_hash()
{
  return ::std::hash<::std::string>()(typeid(T).name());
}
Run Code Online (Sandbox Code Playgroud)

现在,我既不知道hash也不stringconstexpr,但是这可能是周围的工作,承担他们constexpr.我想问的是,如果RTTI打开,constexpr计算哈希值的函数是否typeid(T).name()还会产生编译时常量?什么时候RTTI 关闭?

constexpr c++11

3
推荐指数
1
解决办法
1760
查看次数

如何将constexpr作为模板参数传递?

我有一个模板化的类MyClass,我想为各种参数运行它,以便测量一些值.我知道编译之前的确切参数因此我认为必须有一种方法来实现目标.

我的代码到目前为止:

template <int T>
class MyClass { /*...*/ };


constexpr int PARAMS[] = {1,2,3 /*, ...*/};
for (constexpr auto& t: PARAMS) {
    MyClass<t> myClass;
    // ... do sth
}
Run Code Online (Sandbox Code Playgroud)

但是编译器(gcc v4.9.2,C++ 11)不接受这一点.我也试过使用const而不是constexpr哪个也不行.

有可能是这样的吗?我真的根本不想使用宏.

c++ templates constexpr c++11

3
推荐指数
1
解决办法
1628
查看次数

有人能告诉我为什么这不是一个持续的表达?

我正在尝试使用constexpr编写指向成员函数的链接列表.主要是为了好玩,但它可能有一个有用的应用程序.

struct Foo;

using MethodPtr = void (Foo::*)();

struct Node
{
    constexpr Node(MethodPtr method, const Node* next)
        : Method(method)
        , Next(next)
    {}

    constexpr Node Push(MethodPtr method)
    {
        return Node(method, this);
    }

    MethodPtr Method;
    const Node* Next;
};

struct Foo
{
    constexpr static Node GetMethods()
    {
        return Node{&Foo::Method1, nullptr}
            .Push(&Foo::Method2)
            .Push(&Foo::Method3);
    }

    void Method1() {}
    void Method2() {}
    void Method3() {}
};

int main(void)
{
    constexpr Node node = Foo::GetMethods();
}
Run Code Online (Sandbox Code Playgroud)

上面的代码在调用GetMethods()时主要给出了以下错误:

const Node{MethodPtr{Foo::Method3, 0}, ((const Node*)(& Node{MethodPtr{Foo::Method2, 0}, ((const Node*)(& …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

3
推荐指数
1
解决办法
1280
查看次数

constexpr string vs const string

我们正在将一些代码从c ++ 03迁移到c ++ 14,并且只要有一些性能提升,我们就要使用c ++ 14特性.现在我们的一个项目中我们正在根据列名解析csv列名在一个头文件中声明,如下所示:

const string ITEM_NAME = "Item Name";
const string ITEM_ID = "Item Id";
Run Code Online (Sandbox Code Playgroud)

有这样的一百个常量,所以我想知道的是,如果我将上面的代码更改为这样的代码,是否有任何显着的性能增益:

constexpr string ITEM_NAME = "Item Name";
constexpr string ITEM_ID = "Item Id";
Run Code Online (Sandbox Code Playgroud)

由于需要将它们存储在只读存储器中,因此我们可以在二进制文件中使用constexpr的数量有任何限制吗?

编译器是否也自动优化旧的c ++ 03代码并将const变量也放在只读内存中,这种努力是不值得的?

c++ constexpr c++14

3
推荐指数
1
解决办法
1211
查看次数

const char*constexpr在编译时和运行时进行评估

在以下示例中,我用于static_assert验证是否foo在编译时确定.该static_assert通行证和我有一个不正确的条件下,它实际上是积极的检查.这意味着foo在编译时已知.但是,如果我使用调试器逐步执行代码,我会看到它skip_first_word也在运行时执行.

// Skip the first word in p_str
constexpr const char * skip_first_word(const char * p_str) {
    return (*p_str == '\0') ? p_str : 
        (*p_str == ' ') ? p_str + 1 : 
        skip_first_word(p_str + 1);
}

// constexpr to calculate the length of a string
constexpr size_t str_len(const char * p_str) {
    return (*p_str == '\0') ? 0 : str_len(p_str + 1) + 1;
}

int main()
{
    constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ constexpr c++11 visual-studio-2015

3
推荐指数
1
解决办法
592
查看次数

使用constexpr initializer_list构造函数时,MSVC无法编译

为什么Microsoft Visual C++在编译以下代码时失败?:

template <typename T>
struct slice
{
    size_t length;
    T *ptr;

    constexpr slice(std::initializer_list<T> list)
        : length(list.size()), ptr(list.begin()) {}
};

static_assert(slice<const int>({ 1, 2, 3 }).length == 3, "!!");
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

1>test.cpp(12): error C2131: expression did not evaluate to a constant
1>         visual studio 14.0\vc\include\initializer_list(50): note: failure was caused by an undefined arithmetic operation
Run Code Online (Sandbox Code Playgroud)

initializer_list所有方法的实现都标记了constexpr,看起来它对我来说应该没问题......也许它只是一个编译器问题?

c++ initializer-list visual-c++ constexpr c++11

3
推荐指数
1
解决办法
721
查看次数

constexpr静态成员什么时候停止成为constexpr?

我有这个片段.

#include <iostream>
#include <string>

struct JustStr {
    JustStr(const std::string& x) : val(x) {}
    static constexpr bool pred = false;
    std::string val;
};

template <typename T>
class C {
 private:
    T x;
 public:
    C(T x_) : x(x_) {}
    void f() {
        if constexpr (!x.pred) {
                std::cout << x.val << std::endl;
            }
    }

};

template<typename T>
void f2(T x) {
    T y(x);
    if constexpr (!y.pred) {
            std::cout << x.val << std::endl;
        }
}

int main() {
    C<JustStr> c(JustStr("yes"));
    c.f();  // Fails …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++17 if-constexpr

3
推荐指数
1
解决办法
72
查看次数

C ++中的Constexpr迭代器

我有兴趣为个人项目创建一个非常小的constexpr容器。我需要的最重要的事情是带有真正constexpr迭代器的容器。它们最终将被添加到标准中(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0858r0.html),但是我想知道如何在当前的C ++。

假设我有一个像这样的数据结构:

template <typename T, unsigned N>
struct array {
  const T data[N];

  template<typename... Args>
  constexpr array(const Args&... args) : data{args...} {
}
  struct array_iterator {
    T const* ptr;

    constexpr array_iterator(const T* ptr) : ptr(ptr) {}

    constexpr void operator++() { ++ptr; }
    constexpr void operator--() { --ptr; }
    constexpr T const& operator* () const { return *ptr; }
    constexpr bool operator==(const array_iterator& rhs) const { return *(*this) == *rhs; }
    constexpr bool operator!=(const array_iterator& rhs) const { …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming constexpr c++17

3
推荐指数
1
解决办法
416
查看次数

Constexpr值作为指针类型的非类型模板参数

以下代码

#include <iostream>
#include <initializer_list>

using namespace std;


constexpr initializer_list<int> list = {1, 2, 3};

template<const int* begin, const int* end>
bool contains(int v)
{
    if constexpr(begin != end)
    {
        if (*begin = v)
            return true;
        else
            return contains<next(begin), end>(v);
    }
    return false;
}


int main()
{
    cout << contains<list.begin(), list.end()>(2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产生一些非常奇怪的错误消息:

main.cpp: In function 'int main()':
main.cpp:25:49: error: no matching function for call to 'contains<list.std::initializer_list<int>::begin(), list.std::initializer_list<int>::end()>(int)'
     cout << contains<list.begin(), list.end()>(2);
                                                 ^
main.cpp:10:6: note: candidate: 'template<const …
Run Code Online (Sandbox Code Playgroud)

c++ templates constexpr c++17

3
推荐指数
1
解决办法
122
查看次数