相关疑难解决方法(0)

在编译时计算C字符串的长度.这真的是一个constexpr吗?

我正在尝试在编译时计算字符串文字的长度.为此,我使用以下代码:

#include <cstdio>

int constexpr length(const char* str)
{
    return *str ? 1 + length(str + 1) : 0;
}

int main()
{
    printf("%d %d", length("abcd"), length("abcdefgh"));
}
Run Code Online (Sandbox Code Playgroud)

一切都按预期工作,程序打印4和8.由clang生成的汇编代码显示结果在编译时计算:

0x100000f5e:  leaq   0x35(%rip), %rdi          ; "%d %d"
0x100000f65:  movl   $0x4, %esi
0x100000f6a:  movl   $0x8, %edx
0x100000f6f:  xorl   %eax, %eax
0x100000f71:  callq  0x100000f7a               ; symbol stub for: printf
Run Code Online (Sandbox Code Playgroud)

我的问题:标准是否保证length函数将在编译时进行评估?

如果这是真的,编译时字符串文字计算的大门刚刚为我打开...例如,我可以在编译时计算哈希值等等......

c++ standards string-literals constexpr c++11

86
推荐指数
6
解决办法
2万
查看次数

constexpr重载

相关:函数返回constexpr无法编译

我觉得constexpr在C++ 11中的用处有限,因为无法定义两个本来具有相同签名的函数,但有一个是constexpr而另一个不是constexpr.换句话说,如果我有一个constexpr std :: string构造函数只接受constexpr参数,并且非constexpr std :: string构造函数用于非constexpr参数,那将非常有用.另一个例子是理论上复杂的功能,通过使用状态可以提高效率.使用constexpr函数你不能轻易做到这一点,所以你有两个选择:如果你传入非constexpr参数,那么constexpr函数非常慢,或者完全放弃constexpr(或写两个单独的函数,但你可能不知道要调用哪个版本).

因此,我的问题是:

是否有可能符合标准的C++ 11实现允许基于constexpr参数的函数重载,或者这需要更新标准?如果不允许,是否故意不允许?


@NicolBolas:假设我有一个映射enum到a 的函数std::string.最直接的方式做到这一点,假设我enum去从0n - 1,是创建一个大小的数组n充满了结果.

我可以创建一个static constexpr char const * []并构造一个std::string返回(std::string每次调用函数时支付创建对象的成本),或者我可以创建一个static std::string const []并返回我查找的值,std::string第一次支付所有构造函数的成本调用该函数.似乎更好的解决方案是std::string在编译时创建内存(类似于现在所做的char const *),但是执行此操作的唯一方法是警告构造函数它有constexpr参数.

对于一个除了std::string构造函数之外的例子,我认为找到一个例子是非常简单的,如果你可以忽略constexpr(并因此创建一个非constexpr函数)的要求,你可以创建一个更有效的函数.考虑一下这个帖子:constexpr问题,为什么这两个不同的程序用g ++在不同的时间内运行?

如果我fib用一个constexpr参数调用,我不能比编译器完全优化掉函数调用做得更好.但是,如果我fib使用非constexpr参数调用,我可能希望让它调用我自己的版本来实现memoization(这将需要状态)之类的东西,所以我得到的运行时间类似于我通过constexpr参数时的编译时间.

c++ overloading compile-time-constant constexpr c++11

45
推荐指数
5
解决办法
8601
查看次数

C ++检查语句是否可以评估为constexpr

有没有一种方法可以确定是否可以对constexpr求值,并将结果用作constexpr布尔值?我的简化用例如下:

template <typename base>
class derived
{
    template<size_t size>
    void do_stuff() { (...) }

    void do_stuff(size_t size) { (...) }
public:
    void execute()
    {
        if constexpr(is_constexpr(base::get_data())
        {
            do_stuff<base::get_data()>();
        }
        else
        {
            do_stuff(base::get_data());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的目标是C ++ 2a。

我发现了以下reddit线程,但我不是宏的忠实拥护者。https://www.reddit.com/r/cpp/comments/7c208c/is_constexpr_a_macro_that_check_if_an_expression/

c++ template-meta-programming constexpr c++20 if-constexpr

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

constexpr和一个带有重新解释强制转换的静态const void指针的初始化,哪个编译器是对的?

考虑以下代码:

struct foo {
  static constexpr const void* ptr = reinterpret_cast<const void*>(0x1);
};

auto main() -> int {
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的例子在g ++ v4.9(Live Demo)中编译得很好,但它无法在clang v3.4(Live Demo)中编译并生成以下错误:

错误:constexpr变量'ptr'必须由常量表达式初始化

问题:

  • 根据标准,哪两个编译器是正确的?

  • 声明这种表达的正确方法是什么?

c++ gcc clang constexpr c++11

17
推荐指数
2
解决办法
3691
查看次数