标签: constexpr

pimpl、std::unique_ptr 和 constexpr 构造函数

我正在审查一个非编译代码,其中我发现了与此类似的设计:

巴赫

#include <memory>

class A;

class B {
   private:
    int val;
    // pImpl idiom
    std::unique_ptr<A> pImpl;
    constexpr B(int x): val(x){};
    virtual ~B();
};
Run Code Online (Sandbox Code Playgroud)

析构函数是在 中定义的B.cpp,但构造函数是constexpr它意味着它是在 中定义的B.h。但是编译失败,因为编译器需要有一个 的构造函数A,此时它是一个不完整的类型。但我认为这constexpr是一个设计错误,因为我看不到如何B在编译时使用实现来构造 a 。

因此,constexpr在这种情况下是错误的,还是有办法B在编译时构造 a (我不认为std::unique_ptr可以在编译时构造,除了 from nullptr)?

注意我试图将构造函数定义推入内部,B.cpp但是链接器然后(从逻辑上我认为)触发了构造函数上的未定义引用...
注意编译到目前为止仅在 msvc 上进行了测试注意
我读了一堆关于 pimpl 的帖子并且unique_ptr(它们是很多)但我可能错过了一个足够的问题,而且问题很可能是重复的......

c++ pimpl-idiom unique-ptr constexpr

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

为什么函数可以是 constexpr,即使它们不能在常量表达式中使用?

说明constexpr符声明可以在编译时计算函数或变量的值。函数的唯一用例constexpr是它能够在编译时解析。或者更准确地说,是constexpr用变量的结果初始化变量的能力。如果将函数的结果存储到变量constexprconstexpr,它会强制函数成为纯函数(看起来像,不确定)。

add为什么可以标记该功能constexpr

int global = 200;
constexpr int add(int a) {
    global += a; //works perfectly at run-time but no way to run at compile time
    return global;
}

int main() {
    // will not run since it attempts to access run-time storage,
    // global is not const and so on 
    constexpr int a = add(1);
    // works, but only at run-time, yet the function is constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++20

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

C++ if constexpr 使用 constexpr bool 相当于普通 if?

鉴于正在检查的条件变量已标记为 ,以下代码片段在功能上是否等效constexpr

此外,这是模板化上下文中的正确用法if constexpr还是预期的应用程序。

constexpr bool kOn = false;

// Snippet 1
if (kOn) { return true; }

// Snippet 2
if constexpr (kOn) { return true; }
Run Code Online (Sandbox Code Playgroud)

c++ if-statement constexpr if-constexpr

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

如果没有 constexpr std::uninitialized_copy,std::vector 如何能够成为 constexpr?

我正在实现我自己的容器,并且我试图使其尽可能对 constexpr 友好。

\n

在这个过程中,我发现这std::uninitialized_copy不是 constexpr,因此我无法使用标准算法实现复制分配。

\n

然而, constexprstd::vector 是否友好:

\n
constexpr auto f() {\n    std::vector<int> v = {1, 2, 3};\n    return v.size();\n}\n\nstatic_assert(f() == 3);\n
Run Code Online (Sandbox Code Playgroud)\n

当我替换为我自己的容器时,我无法实现此目的std::vector。\n我收到错误:

\n
... error: call to non-\xe2\x80\x98constexpr\xe2\x80\x99 function \xe2\x80\x98_ForwardIterator std::uninitialized_copy(_InputIterator, ...\n
Run Code Online (Sandbox Code Playgroud)\n

我想知道标准库(例如 stdlib)如何实现这一点。\n它是否使用uninitialized_copyconstexpr 的秘密实现?\nconstexpr uninitalized_copy 是否可以实现?

\n

我想挑战在于拥有constexpr addressofconstexpr construct_at。\n是否有一个我可以回退的实现?

\n

c++ initialization std constexpr

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

为什么 clang 允许在 constexpr 中进行这种 C 风格的转换?

以下代码可以使用 clang++ 14 进行编译,但不能使用 g++ 12 进行编译(由于reinterpret_castconstexpr 中不允许,所以会失败)。

constexpr int* convert(char* a) {
    return (int*)(a);
}

int main() {
    return (int) *convert(new char('a'));
}
Run Code Online (Sandbox Code Playgroud)

为什么 clang 允许这种 C 风格的转换,而 gcc 不允许?

c++ clang constexpr

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

可以在编译时使用`constexpr std :: initializer_list`但不使用ODR吗?

在下面的独立程序中,我for原本期望循环在编译时展开,甚至完全计算,Foo::MyNumbers在链接时不必要:

struct Foo
{
  constexpr static auto MyNumbers =
  {
    3,
    28,
    200,
  };
};

constexpr int getSum(void)
{
  auto sum = 0;
  for (constexpr auto i : Foo::MyNumbers)
  {
    sum += i;
  }
  return sum;
}
Run Code Online (Sandbox Code Playgroud)

然而,即使有-O3,既clang++3.7(从源代码编译之前的3.7版本)和g++5.1给出一个类似的错误; clangread of non-constexpr variable '__begin' is not allowed in a constant expression,虽然g++the value of '__for_begin' is not usable in a constant expression.

我真的不能想到任何可以在编译时有用 …

c++ one-definition-rule constexpr c++11

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

使用constexpr和函数

我正在尝试使用constexpr和static_assert.我实际上需要检查constexpr字符串的长度,该字符串由专用函数计算.这是我正在尝试运行的:

#include <iostream>
using namespace std;

class Test
{
    private :
        static constexpr char str[] = "abc";

        static int constexpr constStrLength(const char* str)
        {
            return *str ? 1+constStrLength(str+1) : 0;
        }
        static constexpr int length = constStrLength(str);
        static_assert(length ==3, "error");

    public :
        static void f()
        {
            cout << len << endl;
        }
};

int main()
{
    Test::f();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误:

错误:'static constexpr int Test :: constStrLength(const char*)'在常量表达式中调用static constexpr int len = constStrLength("length");

什么是实现它的正确方法?

感谢帮助 !

c++ constexpr

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

constexpr替换宏而不回归

在我们公司的代码中我们使用64位标志枚举:

enum Flags : unsigned long long {
    Flag1 =  1uLL<<0, // 1
    //...
    Flag40 = 1uLL<<40 // 1099511627776
};
Run Code Online (Sandbox Code Playgroud)

并添加注释以查看每个标志十进制值,即使我们在文本查看器中读取代码.问题是没有什么能阻止开发人员在评论中输入错误的数字.

有一个解决这个问题的方法 - 一个带有static_assert +宏的模板可以轻松使用这种方法 - 无需使用括号并在所有地方添加:: val:

template <unsigned long long i, unsigned long long j>
struct SNChecker{
    static_assert(i == j, "Numbers not same!");
    static const unsigned long long val = i;
};

#define SAMENUM(i, j) SNChecker<(i), (j)>::val

enum ET : unsigned long long {
    ET1 =     SAMENUM(1uLL<<2, 4),
    ET2fail = SAMENUM(1uLL<<3, 4), // compile time error
    ET4 = …
Run Code Online (Sandbox Code Playgroud)

c++ macros compile-time constexpr

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

比较constexpr-if条件中的constexpr函数参数会导致错误

我正在尝试比较constexpr-if语句中的函数参数.

这是一个简单的例子:

constexpr bool test_int(const int i) {
  if constexpr(i == 5) { return true; }
 else { return false; }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我用GCC 7使用以下标志编译它时: g++-7 -std=c++1z test.cpp -o test 我收到以下错误消息:

test.cpp: In function 'constexpr bool test_int(int)':
test.cpp:3:21: error: 'i' is not a constant expression
 if constexpr(i == 5) { return true; }
Run Code Online (Sandbox Code Playgroud)

但是,如果我test_int用不同的功能替换:

constexpr bool test_int_no_if(const int i) { return (i == 5); }
Run Code Online (Sandbox Code Playgroud)

然后以下代码编译没有错误:

int main() {
  constexpr int i = 5;
  static_assert(test_int_no_if(i));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么constexpr-if版本无法编译,特别是因为static_assert工作正常. …

c++ static-assert constexpr c++17 if-constexpr

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

有没有一种方法可以构造一个constexpr函数来获取double的位表示形式?

是否有构造constexpr函数的标准方法,该函数允许将double转换为其64位表示形式:

constexpr uint64_t double_to_uint64_t(double d) {
   ??????
}
Run Code Online (Sandbox Code Playgroud)

以便

constexpr uint64_t two_bits = double_to_uint64_t(2.0);
Run Code Online (Sandbox Code Playgroud)

会编译吗?

反向方法(uint64变为double)也很有趣。

c++ constexpr c++11

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