我正在研究一个已知只能在Windows上运行并在Visual Studio下编译的代码库(它与excel紧密集成,所以它不会去任何地方).我想知道我是否应该使用传统的包含警卫或#pragma once用于我们的代码.我认为让编译器处理#pragma once会产生更快的编译,并且在复制和粘贴时不易出错.它也稍微不那么难看;)
注意:为了获得更快的编译时间,我们可以使用Redundant Include Guards,但这会在包含的文件和包含文件之间增加紧密耦合.通常它没关系,因为防护应该基于文件名,并且只有在你需要改变包含名称时才会改变.
const static int foo = 42;
Run Code Online (Sandbox Code Playgroud)
我在StackOverflow上的一些代码中看到了这个,我无法弄清楚它是做什么的.然后我在其他论坛上看到了一些困惑的答案.我最好的猜测是它在C中用来隐藏foo其他模块的常量.它是否正确?如果是这样,为什么有人会在C++上下文中使用它,你可以做到这一点private?
在2016年奥卢ISO C++标准会议上,一项名为Inline Variables的提案被标准委员会投票选为C++ 17.
通俗地说,什么是内联变量,它们如何工作以及它们对什么有用?如何声明,定义和使用内联变量?
好吧,无论如何不是C/C++专家,但我认为头文件的目的是声明函数,然后C/CPP文件来定义实现.
但是,今晚回顾一些C++代码,我发现这是在类的头文件中...
public:
UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh??
private:
UInt32 _numberChannels;
Run Code Online (Sandbox Code Playgroud)
那么为什么标题中有实现呢?是否与const关键字有关?这是内联类方法吗?与定义CPP文件中的实现相比,这样做的好处/意义究竟是什么?
我可以将extern和const混合为extern const吗?如果是,const限定符是否仅在其声明的范围内强加它的统治,或者它是否应与它声明的转换单元的声明完全匹配?即extern const int i;即使实际的i不是const,反之亦然,我可以声明说吗?
我刚刚发现以下内容无效.
//Header File
class test
{
const static char array[] = { '1', '2', '3' };
};
Run Code Online (Sandbox Code Playgroud)
初始化这个的最佳位置在哪里?
constexpr说明noexcept符是否意味着函数的说明符?对类似问题的回答对说明者说"是" inline,但Eric Niebler的文章让我想知道对当前问题的可能答案.在我看来,答案取决于使用constexpr函数的上下文:是常量表达式上下文还是运行时上下文,即在编译时是否已知函数的所有参数.
我希望答案是"是",但简单的检查表明情况并非如此.
constexpr
bool f(int) noexcept
{
return true;
}
constexpr
bool g(int)
{
return true;
}
static_assert(noexcept(f(1)));
static_assert(noexcept(g(2))); // comment this line to check runtime behaviour
#include <cassert>
#include <cstdlib>
int
main(int argc, char * [])
{
assert(noexcept(f(argc)));
assert(noexcept(g(argc)));
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud) 假设您有一个为您的应用程序生成一些安全性令牌的函数,例如一些哈希盐,或者可能是对称或非对称密钥.
现在假设您在C++中将此函数作为constexpr,并根据某些信息(例如,构建号,时间戳,其他内容)为构建生成密钥.
你是一个勤奋的程序员,确保并以适当的方式调用它,以确保它只在编译时被调用,因此死剥离器从最终的可执行文件中删除代码.
但是,您无法确定其他人是否会以不安全的方式调用它,或者编译器可能不会删除该功能,然后您的安全令牌算法将成为公共知识,使其成为公共知识更容易让攻击者猜测未来的令牌.
或者,除了安全性之外,假设该函数需要很长时间才能执行,并且您希望确保它在运行时期间永远不会发生,并且会给最终用户带来糟糕的用户体验.
有没有办法确保在运行时永远不会调用constexpr函数?或者,在运行时抛出一个断言或类似的东西就可以了,但不像编译错误那样明显.
我听说有一些方法涉及抛出一个不存在的异常类型,所以如果constexpr函数没有被删除,你会得到一个链接器错误,但是听说这只适用于某些编译器.
远程相关的问题:强制constexpr在编译时进行评估
当我尝试编译以下代码时,我得到一个链接器错误:Undefined symbols for architecture x86_64: "Foo()", referenced from: _main in main.o使用LLVM 4.2.
仅在标记函数时才会出现此问题constexpr.当标记功能时,程序会正确编译和链接const.为什么声明该函数constexpr会导致链接器错误?
(我意识到以这种方式编写函数不会带来编译时计算的好处;此时我很好奇为什么函数无法链接.)
main.cpp中
#include <iostream>
#include "test.hpp"
int main()
{
int bar = Foo();
std::cout << bar << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
test.hpp
constexpr int Foo();
Run Code Online (Sandbox Code Playgroud)
TEST.CPP
#include "test.hpp"
constexpr int Foo()
{
return 42;
}
Run Code Online (Sandbox Code Playgroud) 我想知道是否有必要声明constexpr函数和方法的限制,就像内联函数和方法一样.
我知道必须在头文件中编写内联函数或方法,以使编译器能够访问它们被调用的定义.如果constexpr有类似的东西会有意义,但我无法找到关于这一点的任何东西......
基本上我的问题是:
我是否可以在头文件中编写constexpr函数的定义而不会冒重复符号的风险?
我可以分离constexpr函数或方法的声明和定义吗?
我正在处理一些constexpr使用函数的代码,我目前consteval尽可能将其重构为。
inline constexpr auto example() noexcept { /*...*/ }
Run Code Online (Sandbox Code Playgroud)
据我了解,inline上面的关键字在constexpr函数中已经是多余的了。
据我所知,noexcept关键字对于consteval函数来说是多余的,因为据我所知,它consteval必须在编译时进行评估,因此意味着 noexcept。这是真的还是我目前不考虑的东西(比如 constexpr exceptions)?
consteval auto example() { /*...*/ }
Run Code Online (Sandbox Code Playgroud) 我有两个文件的源代码.
第一个文件包含int main()函数的功能和声明以及用法constexpr int square(int x).
// File: foo.cpp
#include <iostream>
constexpr int square(int x);
int main()
{
int a = square(10);
std::cout << "a: " << a << "\n";
}
Run Code Online (Sandbox Code Playgroud)
第二个文件包含constexpr int square(int x)函数的定义.
// File: bar.cpp
constexpr int square(int x)
{
return x * x;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译这两个文件时,我收到以下错误.
$ g++ -std=c++11 bar.cpp foo.cpp
foo.cpp:4:15: warning: inline function ‘constexpr int square(int)’ used but never defined
constexpr int square(int x);
^
/tmp/cc7iwVDZ.o: In function `main': …Run Code Online (Sandbox Code Playgroud)