我正在审查一个非编译代码,其中我发现了与此类似的设计:
巴赫
#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(它们是很多)但我可能错过了一个足够的问题,而且问题很可能是重复的......
说明constexpr符声明可以在编译时计算函数或变量的值。函数的唯一用例constexpr是它能够在编译时解析。或者更准确地说,是constexpr用变量的结果初始化变量的能力。如果将函数的结果存储到变量constexpr中constexpr,它会强制函数成为纯函数(看起来像,不确定)。
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) 鉴于正在检查的条件变量已标记为 ,以下代码片段在功能上是否等效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) 我正在实现我自己的容器,并且我试图使其尽可能对 constexpr 友好。
\n在这个过程中,我发现这std::uninitialized_copy不是 constexpr,因此我无法使用标准算法实现复制分配。
然而, constexprstd::vector 是否友好:
constexpr auto f() {\n std::vector<int> v = {1, 2, 3};\n return v.size();\n}\n\nstatic_assert(f() == 3);\nRun Code Online (Sandbox Code Playgroud)\n当我替换为我自己的容器时,我无法实现此目的std::vector。\n我收到错误:
... error: call to non-\xe2\x80\x98constexpr\xe2\x80\x99 function \xe2\x80\x98_ForwardIterator std::uninitialized_copy(_InputIterator, ...\nRun Code Online (Sandbox Code Playgroud)\n我想知道标准库(例如 stdlib)如何实现这一点。\n它是否使用uninitialized_copyconstexpr 的秘密实现?\nconstexpr uninitalized_copy 是否可以实现?
我想挑战在于拥有constexpr addressof和constexpr construct_at。\n是否有一个我可以回退的实现?
以下代码可以使用 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 不允许?
在下面的独立程序中,我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给出一个类似的错误; clang说read 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.
我真的不能想到任何可以在编译时有用 …
我正在尝试使用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");
什么是实现它的正确方法?
感谢帮助 !
在我们公司的代码中我们使用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) 我正在尝试比较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工作正常. …
是否有构造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++ ×10
constexpr ×10
c++11 ×2
if-constexpr ×2
c++17 ×1
c++20 ×1
clang ×1
compile-time ×1
if-statement ×1
macros ×1
pimpl-idiom ×1
std ×1
unique-ptr ×1