我可以很容易地说,通过将函数声明为constexpr,我们可以在编译时对其进行评估,这可以节省运行时的时间,因为结果已经生成了。
另一方面,虚函数需要在运行时解析。因此,我想我们无法摆脱解决过程。由于函数的机制,只能快速获取结果constexpr。
函数还有其他好处吗constexpr virtual?
我想做的正是标题所说的。我有一些带有 API 的第三方代码。
评估函数所需的信息都应该在编译时可用以评估该函数。但第三方似乎并没有给它贴上constexpr悲伤的标签。此外,我没有完整实现的源代码,只有很多的标头。看起来它可能使用共享对象来评估调用,因为在深入研究 API 的头文件后,很多东西似乎都被标记为外部。由于这些调用并不是constexpr每次我尝试调用它以用于static_assert()编译时都会失败。
如何使该函数在编译时运行并在constexpr函数中使用结果来解决static_assert()条件?所有输入在编译时都是已知的。不需要外部数据。
我刚刚在 ubuntu 20.04 上将编译器升级到 C++20。g++ version给我以下输出:
c++ (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0\nRun Code Online (Sandbox Code Playgroud)\n我正在按照stackoverflow上的建议尝试以下代码
\nconstexpr int f() {\n std::vector<int> v = {1, 2, 3};\n return v.size();\n}\n\nint main() {\n static_assert(f() == 3);\n}\nRun Code Online (Sandbox Code Playgroud)\n但我收到以下错误:
\nerror: variable \xe2\x80\x98v\xe2\x80\x99 of non-literal type \xe2\x80\x98std::vector<int>\xe2\x80\x99 in \xe2\x80\x98constexpr\xe2\x80\x99 function\nRun Code Online (Sandbox Code Playgroud)\n我是不是哪里出错了。或者是我的安装不正确
\nC++ 不允许 constexpr 内联汇编有充分的理由吗?为什么 C++20 中允许未计算的内联汇编表达式?
constexpr有没有办法在编译器指令之前定义它#if作为其输入?换句话说,可以#if有来自 的输入constexpr吗?如果不是,是否意味着#if指令在 之前被评估constexpr?
constexpr int enable_debug = true;
#if (enable_debug)
std::string debug_logs;
#endif
for(int i=0;i<10;i++) {
f(i);
#if (enable_debug)
debug_logs += std::to_string(i);
#endif
}
#if (enable_debug)
std::court << debug_logs;
#endif
Run Code Online (Sandbox Code Playgroud)
这个问题有两个目的:
“指令时间”或“编译指示时间”是否早于编译时间?
我只想有条件地构建一些代码,但代码定义了一个变量,所以我不能使用if constexpr().
为了轻松地重写一个大的 switch-case,我正在尝试像这样的 constexpr 函数模板(它只是一个只有 cout 的简化版本):
#include <iostream>
template<int T>
constexpr void bigSwitchCase(const int idx)
{
if (T == 1 && T == idx)
{
std::cout << 1 <<std::endl;
return;
}
if (T == idx)
{
std::cout << T << std::endl;
}
else if (T > 1)
{
bigSwitchCase<T - 1>(idx);
}
return;
}
template<>
void bigSwitchCase<1>(const int idx)
{
if (1== idx)
{
std::cout << 1 <<std::endl;
return;
}
}
int main()
{
bigSwitchCase<64>(15);
//bigSwitchCase<4096>(15);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但问题是它生成的代码不如以下版本那么快: …
我有两个类A和B,其中B包含A的数组。我会得到B的这个构造函数的编译器错误(抱怨A的默认构造函数无法被引用),除非A的默认构造函数没有被删除。我对这个编译问题的理解是,通过编写 B 的这个构造函数,由于缺少初始化列表,编译器会假设向其中添加 A 的默认构造函数,这将导致错误,因为它被删除了。我怎样才能摆脱这个错误?
constexpr int data[] = {1,2,3,4,5};
constexpr size_t N = sizeof(data)/sizeof(int);
struct A {
A() = delete; // error in B constructor if using this
// constexpr A() = default; // no error if using this instead
constexpr A(int a): a_(a) {}
private:
int a_ = 0;
};
struct B{
constexpr B() { // error: the default constructor of A cannot be referenced
for(size_t i = 0; i < N; i++) arr_[i] = A(data[i]);
}
private: …Run Code Online (Sandbox Code Playgroud) 我尝试constexpr将 ipv4 地址解析为四位数字,但它不起作用。所以我将代码精简到失败的地方:
#include <cstdint>
#include <stdexcept>
#include <string_view>
#define WORKS 1
static constexpr uint8_t
getIpVal(const std::string_view &sv) noexcept {
size_t pos = 0;
auto len = sv.size();
unsigned long val = 0;
while (sv[pos] >= '0' && sv[pos] <= '9' && pos < len) {
int digit = sv[pos] - '0';
val *= 10;
val += digit;
if (val > UINT8_MAX) {
return 0;
// throw std::invalid_argument(sv.data());
}
++pos;
}
if (pos < len) {
return 0; …Run Code Online (Sandbox Code Playgroud) 以下代码在编译期间初始化两个 const 字符串:
class Test
{
public:
static constexpr const char* LOS = "Los ";
static constexpr const char* ANGELES = "Angeles";
};
Run Code Online (Sandbox Code Playgroud)
如何创建另一个常量字符串(const char*或const std::string)作为两个常量字符串的串联?添加以下行
static constexpr const std::string LOS_ANGELES = std::string(LOS).append(ANGELES);
Run Code Online (Sandbox Code Playgroud)
发出错误:
error: the type ‘const string {aka const std::basic_string<char>}’ of constexpr variable ‘Test::LOS_ANGELES’ is not literal
Run Code Online (Sandbox Code Playgroud) 我们转到了新的编译环境,突然间我开始在此语句上看到此错误“期望的表达式”:
enum {
PROJX,
PROJY,
PROJW
};
constexpr int PLATFORM =
#if defined(X)
PROJX
#elif defined(Y)
PROJY
#elif defined(W)
PROJW
#endif
;
Run Code Online (Sandbox Code Playgroud)
错误指向最后一个分号。
这与特定的c ++ 11/14/17标准有关吗?
不同的C ++功能的编译时间是多少?我有兴趣选择正确的方法来在我的库头文件中实现一些通用代码,并且我想花一些时间为图书馆用户考虑。粗略和/或相对的数字就可以了。
我对以下情况特别感兴趣:
{ return true; })PS:请不要谈论我过早的优化。无论如何,有关编译时间的信息将对C ++开发人员很有趣。
更新:阐明了我正在优化的代码在库头文件中,因此其编译时间对于库用户而言绝对重要。
更新:改写该问题以免引起别人的疑问。
基本问题:
编辑:v-问题-v
class foo {
public:
constexpr foo() { }
constexpr int operator()(const int& i) { return int(i); }
}
Run Code Online (Sandbox Code Playgroud)
性能是一个非常重要的问题.编译器如何实际编译以上内容?我知道我希望如何解决它,但规范如何实际指定它将被解决?
1)看到int类型有一个constexpr构造函数,创建一个int对象并编译字节串,使得从内存中的类型直接进入代码?
2)通过调用'int的构造函数来替换对重载的任何调用,由于某些未知的原因,int没有constexpr构造函数?(内联电话.)
3)创建一个函数,调用该函数,并让该函数调用'int的consctructor?
为什么我想知道,以及我打算如何使用这些知识
编辑:v-Background only-v
我正在使用的真实库使用模板参数来决定如何在函数之间传递给定类型.也就是说,通过引用或值,因为类型的确切大小是未知的.用户有责任在我给他们的限制范围内工作,但我希望这些限制尽可能轻松和用户友好,因为我可以很好地制作它们.
我希望传递一个简单的单字节字符,在这种情况下它应该通过值传递.每次调用复制构造函数时,我都不会禁止 300兆字节的庞然大物进行几次重新计算.在这种情况下,通过引用传递更有意义.我只有一个类型必须遵守的要求列表,而不是对类型可以或不可以做什么设置上限.
为什么我想知道我的问题的答案是这样我才能真诚地创建一个接受这个未知模板的函数对象,然后决定如何,何时,甚至应该复制多少对象.通过虚拟成员函数和分配有new的指针是如此需要的.如果编译器严重解决constexpr我需要知道,所以我可以抛弃这种思路和/或找到一个新思路.同样,用户有责任在我给他们的限制范围内工作,但我希望这些限制尽可能轻松和用户友好,因为我可以很好地制作它们.
编辑:谢谢你的回答.唯一真正的问题是第二句话.现在已经回答了.其他所有如果需要更多背景,请允许我重申以上内容:
我有一个带有四个参数的模板.模板的目标是路由协议.是TCP/IP -unlikely-或节点内的节点 - 可能.前两个用于数据存储.除了每个运营商列表之外,他们没有要求.最后两个定义了数据在模板中的传递方式.默认情况下,这是参考.为了性能和使用自由,可以根据用户的请求更改这些定义以按值传递信息.
每个都期望长一个字节.对于EIGRP或类似OSFP协议的度量,它们可以是第二个模板参数可以是十几个或更多个不同变量的复合.每个人都需要非繁琐的时间来复制或重新计算.
为了便于使用,我研究了使用一个接受第三和第四个模板的函数对象来处理无法正常运行或复制的特殊情况和多态类.该目标不强制用户从头开始重建他们的对象.这将需要规划虚拟功能以执行深拷贝或任何数量的其他未知奇数.函数对象的用处取决于编译器如何依赖于不生成级联的函数调用.
我希望更有帮助吗?
谢谢,我不需要任何书来教我什么constexpr意思.我正在教学constexpr,我的简单例子无法说服学生为什么应该利用编译时计算的优势constexpr.
还请严格避免链接到问题,比如这个它没有汇编代码或分析,他们是没有意义的,我的问题.
我正在寻找一个例子来说明为什么constexpr它有用并且不能被解雇.
好吧,在很多情况下如果constexpr被替换为const没有错,确实会发生.所以,我设计了以下示例:
main_const.cpp
#include <iostream>
using namespace std;
const int factorial(int N)
{
if(N<=1)
return 1;
else
return N*factorial(N-1);
}
int main()
{
cout<<factorial(10)<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和
main_constexpr.cpp
#include <iostream>
using namespace std;
constexpr int factorial(int N)
{
if(N<=1)
return 1;
else
return N*factorial(N-1);
}
int main()
{
cout<<factorial(10)<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但问题是,对于他们以前的那个,汇编代码是
main_const.asm
12:main_last.cpp **** int main()
13:main_last.cpp **** {
132 .loc …Run Code Online (Sandbox Code Playgroud)