我想为我当前的问题使用一组位标志.这些标志(很好地)被定义为一部分enum,但是据我所知,当你OR从枚举中获得两个值时,OR操作的返回类型具有类型int.
我目前正在寻找的是一种解决方案,它允许位掩码的用户保持类型安全,因此我创建了以下重载 operator |
enum ENUM
{
ONE = 0x01,
TWO = 0x02,
THREE = 0x04,
FOUR = 0x08,
FIVE = 0x10,
SIX = 0x20
};
ENUM operator | ( ENUM lhs, ENUM rhs )
{
// Cast to int first otherwise we'll just end up recursing
return static_cast< ENUM >( static_cast< int >( lhs ) | static_cast< int >( rhs ) );
}
void enumTest( ENUM v )
{
}
int …Run Code Online (Sandbox Code Playgroud) 目前我正在阅读C++的1篇论文,目前我正在尝试理解n3873题为" 改进的插入接口的独特键映射"的论文.该文件指出insert和emplace方法存在问题,它说明了以下示例的问题:
std::map<std::string, std::unique_ptr<Foo>> m;
m["foo"];
std::unique_ptr<Foo> p(new Foo);
auto res = m.emplace("foo", std::move(p));
Run Code Online (Sandbox Code Playgroud)
在上面的代码之后,它表达了以下内容:
有什么价值
p?目前p尚未说明是否已移出.(答案是它取决于库的实现.)
好吧,我在寻找前一个引用的解释时遇到了麻烦,主要是因为我无法找到标准中指定的位置,如上所述移动或不移动的代码p是实现定义的; 期待n3690标准关联容器部分(23.2.4)关于emplace(args)(插入一个用它构造的value_type对象)和方法只提到插入或放置了值...tstd::forward<Args>(args)insert(t)
...当且仅当容器中没有元素且密钥等于密钥的时候
t.
关于移动(或不移动)t价值的一句话; 另一方面,p托管内存无论如何都被释放(如果p在没有插入后移动被释放,并且如果没有被移动则在范围的末尾被释放)不是吗?
介绍之后,让我问下列问题:
p这个例子会发生什么?它真的被释放了吗?如果问题看起来很愚蠢或有明显的答案,请尝试原谅,这可能是因为我缺乏英语理解能力,或者因为我不习惯潜入标准论文.任何指导将不胜感激.
如果我需要foo使用template-template参数定义模板函数,我通常会执行以下操作:
// Notice that the template parameter of class T is unnamed.
template <template <typename> class T> void f() { std::cout << "Yay!\n"; }
Run Code Online (Sandbox Code Playgroud)
请注意,template-template参数的template参数是未命名的,但我们可以为此参数指定一个名称:
// Now the template parameter of class T is named INNER.
template <template <typename INNER> class T> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
Run Code Online (Sandbox Code Playgroud)
这似乎没有用,因为我无法INNER在函数中提供参数,上面的代码会产生以下错误:
错误:'INNER'未命名类型
令我惊讶typename INNER的typename是,在为了命名类型之后,所有关键字都没有命名类型.无论如何,这很容易修复:
// Now INNER is the name of the template parameter of class T and …Run Code Online (Sandbox Code Playgroud) 我已经使用硬件API很长一段时间了,几乎所有我工作过的API都有一个C接口.因此,在很多时候我使用裸news,不安全的缓冲和许多用C++代码包装的C函数.最后,C纯代码和C++纯代码之间的边界在我的脑海中搞砸了(我不知道澄清这个前沿是否有用).
现在,由于一些新的编码风格要求,我需要将所有怀疑不安全的代码重构为用C++编写的更安全的代码(假设C++代码更安全),最终目标是使用C++带来的工具.
所以,为了摆脱我的困惑,我正在寻求关于C/C++的几个主题的帮助.
memcpy VS std::copyAFAIK memcpy是一个位于C库中的函数,因此它不是C++ ish; 另一方面std::copy是STL中的一个函数,所以它是纯C++.
std::copy则会调用std::memcpy(进入cstring标题).memcpy调用重构为std::copy调用将使代码更"纯C++"?为了处理新的代码样式要求,我决定继续使用memcpy重构,有一些关于memcpy和的问题std::copy:
memcpy类型不安全,因为它适用于原始void指针,可以管理任何类型的指针,无论它的类型如何,但同时非常灵活,std::copy缺乏这种灵活性,确保类型安全.乍一看,memcpy是使用序列化和反序列化例程的最佳选择(这是我确实使用的真实情况),例如,通过自定义串行端口库发送一些值:
void send(const std::string &value)
{
const std::string::size_type Size(value.size());
const std::string::size_type TotalSize(sizeof(Size) + value.size());
unsigned char *Buffer = new unsigned char[TotalSize];
unsigned char *Current = Buffer;
memcpy(Current, &Size, sizeof(Size));
Current += sizeof(Size);
memcpy(Current, value.c_str(), Size);
sendBuffer(Buffer, TotalSize);
delete []Buffer;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码运行正常,但看起来很糟糕; …
最近一位同事向我展示了这样的代码:
void SomeClass::function()
{
static bool init = false;
if (!init)
{
// hundreds of lines of ugly code
}
init = true;
}
Run Code Online (Sandbox Code Playgroud)
他想检查是否SomeClass已初始化,以便每个Someclass实例执行一次代码,但事实是SomeClass在程序的所有生命周期中只存在一个实例.
他的问题是关于init静态变量,关于何时初始化.我已回答初始化发生一次,因此该值将false在第一次调用true时及其生命周期的剩余时间.在回答之后,我已经补充说这样使用静态变量是不好的做法,但我无法解释原因.
到目前为止我一直在考虑的原因如下:
static bool initinto 的行为SomeClass::function.SomeClass无法检查static bool init值,因为它的可见性仅限于void SomeClass::function()范围.这个原因看起来很糟糕,不完整,对我来说不是很具体,所以我要求更多理由来解释为什么在函数和成员函数空间中使用静态变量是一种不好的做法.
谢谢!
有没有办法让用户在C或C++中输入二进制数?
如果我们写类似的东西
int a = 0b1010;
std::cout << a << std::endl
Run Code Online (Sandbox Code Playgroud)
然后输出结果为10(使用适当的编译器扩展时).
但是当我们试着写的时候
int n;
std::cin >> n;
int t = 0bn;
Run Code Online (Sandbox Code Playgroud)
它给了我们一个错误所以任何人都可以建议我们如何直接读取二进制数作为输入而不是使用字符串来存储输入?
我想有一个嵌套值的模板,应该由给定的初始化函数初始化:
template <typename T, T(INIT)()> struct Foo
{
T value = INIT();
};
Run Code Online (Sandbox Code Playgroud)
它可以这样使用:
// Some random type only instanceable through factory()
struct Bar
{
int bar{};
private:
// The only way to create a Bar is through factory()
friend Bar factory();
Bar() {};
};
Bar factory() { return {}; }
Foo<Bar, factory> foo;
Run Code Online (Sandbox Code Playgroud)
但是,如果没有提供函数,模板应该尝试默认初始化嵌套值,所以我试图专门化模板:
template <typename T> struct Foo<T, nullptr>
{
T value{};
};
Run Code Online (Sandbox Code Playgroud)
我的想法是这样使用它:
struct Baz{};
Foo<Bar, factory> foo; // Nested Bar have Bar::bar initialized through factory function. …Run Code Online (Sandbox Code Playgroud) 在阅读了关于控制主题的答案到达非void函数的结尾之后,我没有看到任何答案,特别是使用空return语句退出非void函数的情况:
int return_integer() { return; } // empty return in non-void function
Run Code Online (Sandbox Code Playgroud)
到目前为止我在C标准中发现的是:
6.8.6.4退货声明
约束
return带有表达式的语句不应出现在返回类型为的函数中void.return没有表达式的语句只能出现在返回类型为的函数中void.
标准引用说明我们应该对我们的return语句void和非void函数做什么,当忽略约束时会发生什么,在文档的其他部分中提到:
6.9.1函数定义
- 如果
}终止了函数,并且调用者使用了函数调用的值,则行为是未定义的.
以前的标准引用声明,如果我们使用函数的返回值,并且在到达结束花括号(})之后结束,则会发生UB ,因此我们在下面的代码中有UB:
int UB(int x) { if (x) return x; }
printf("%d", UB(1)); // Correct
printf("%d", UB(0)); // Undefined behavior
Run Code Online (Sandbox Code Playgroud)
在UB(1)调用中函数1通过下面的return x;指令返回if (x); 在UB(0)调用中 …
可能重复:
文件范围内可变修改的数组
我有一些关于VLA及其行为的概念,我需要澄清一下.
自C99起AFIK可以将VLA声明为本地范围:
int main(int argc, char **argv)
{
// function 'main' scope
int size = 100;
int array[size];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但它在全球范围内被禁止:
const int global_size = 100;
int global_array[global_size]; // forbidden in C99, allowed in C++
int main(int argc, char **argv)
{
int local_size = 100;
int local_array[local_size];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在C99中声明了一个VLA,因为const修饰符不会创建编译时值.在C++中global_size是一个编译时值,因此,global_array不会成为VLA.
我需要知道的是:我的推理是否正确?我描述的行为是正确的吗?
我也想知道:为什么不允许全球范围内的VLA?在C和C++中是否被禁止?数组在全局和局部范围内的行为有什么不同?
几天前,在阅读标准C++新闻时,我读过有关C++ 11中默认函数的帖子,在那篇文章中提到用户定义的构造函数效率低于编译器生成的函数:
用户定义的默认构造函数的效率低于编译器隐式定义的默认构造函数.
继续阅读,有一个例子,用户定义的构造函数被标记为默认值,然后说:
显式默认构造函数比手动编程的默认构造函数更有效.
我不明白这些断言,所以我想知道: