- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我最近从 Scott Meyers 那里购买了新的 Effective现代 C++ 并通读了它。但是我遇到了一件让我非常烦恼的事情。
在第 5 项中,Scott 说使用 auto
是一件很棒的事情。它可以节省输入,在大多数情况下为您提供正确的类型,并且可能不受类型不匹配的影响。我完全理解这一点并想到了 auto
也是一件好事。
但是在第 6 项中,斯科特说每个硬币都有两个面。同样,可能存在 auto
的情况推导出完全错误的类型,例如用于代理对象。
你可能已经知道这个例子:
class Widget;
std::vector<bool> features(Widget w);
Widget w;
bool priority = features(w)[5]; // this is fine
auto priority = features(w)[5]; // this result in priority being a proxy
// to a temporary object, which will result
// in undefined behavior on usage after that
// line
auto priority = static_cast<bool>(features(w)[5]);
auto
的两个优势在显式给定类型上。
auto priority = static_cast<bool>(features(w)[5]);
bool priority = features(w)[5];
Guideline: Consider declaring local variables auto x = type{ expr }; when you do want to explicitly commit to a type. It is self-documenting to show that the code is explicitly requesting a conversion, it guarantees the variable will be initialized, and it won’t allow an accidental implicit narrowing conversion. Only when you do want explicit narrowing, use ( ) instead of { }.
bool priority = features(w)[5];
auto priority = static_cast<bool>(features(w)[5]);
auto priority = bool(features(w)[5]);
auto priority = bool{features(w)[5]};
最佳答案
遵循 C++ 标准:
§ 8.5 Initializers
[dcl.init]
The initialization that occurs in the form
T x = a;
as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization.
auto x = features(w)[5];
template <typename A>
void foo(A x) {}
foo(features(w)[5]);
auto bar()
{
return features(w)[5];
}
auto lambda = [] (auto x) {};
lambda(features(w)[5]);
static_cast<T>
移动到赋值的左侧”。
/*1*/ foo(static_cast<bool>(features(w)[5]));
/*2*/ return static_cast<bool>(features(w)[5]);
/*3*/ lambda(static_cast<bool>(features(w)[5]));
static_cast<T>
是一种强制所需类型的优雅方式,或者可以通过显式构造函数调用来表示:
foo(bool{features(w)[5]});
Whenever you want to force the type of a variable, use
auto x = static_cast<T>(y);
instead ofT x{y};
.
The type inference with
auto
is cool, but may end up with undefined behavior if used unwisely.
If the compiler's regular type-deduction mechanism is not what you want, use
static_cast<T>(y)
.
bool priority = features(w)[5];
auto priority = static_cast<bool>(features(w)[5]);
auto priority = bool(features(w)[5]);
auto priority = bool{features(w)[5]};
std::vector<bool>::reference
是
不是隐含的 可转换为
bool
:
struct BoolReference
{
explicit operator bool() { /*...*/ }
};
bool priority = features(w)[5];
将
不编译 ,因为它不是一个明确的 bool 上下文。其他的会正常工作(只要
operator bool()
是可访问的)。
std::vector<bool>::reference
以旧方式实现,尽管转换运算符不是
explicit
,它返回
int
反而:
struct BoolReference
{
operator int() { /*...*/ }
};
auto priority = bool{features(w)[5]};
初始化,如使用
{}
防止缩小(将
int
转换为
bool
是)。
bool
呢?完全没有,但关于一些用户定义的类型,令我们惊讶的是,声明
explicit
构造函数:
struct MyBool
{
explicit MyBool(bool b) {}
};
MyBool priority = features(w)[5];
初始化将
不编译 ,因为复制初始化语法需要非显式构造函数。其他人会工作。
auto priority = bool{features(w)[5]};
features(w)[5]
真的是 .
auto x = T{y};
的显式类型初始化器的观点。形式(尽管它与
auto x = static_cast<T>(y)
不同,因此并非所有参数都适用)超过
T x{y};
, 哪个是:
auto
变量必须始终被初始化。也就是说,你不能写auto a;
,就像你可以写容易出错的 int a;
auto f = 3.14f;
// ^ float
auto s = "foo"s;
// ^ std::string
auto func(double) -> int;
auto func = [=] (double) {};
using dict = set<string>;
template <class T>
using myvec = vector<T, myalloc>;
auto x = T{y};
<category> name = <type> <initializer>;
T x{y}
相比,使用复制省略和非显式复制/移动构造函数,它的成本为零。句法。 unique_ptr<Base> p = make_unique<Derived>(); // subtle difference
auto p = unique_ptr<Base>{make_unique<Derived>()}; // explicit and clear
{}
保证没有隐式转换和缩小。 auto x = T{}
的一些缺点。一般形式,在这篇文章中已经描述过:
auto x = std::atomic<int>{}; // fails to compile, copy constructor deleted
-fno-elide-constructors
),则移动不可移动类型会导致昂贵的复制: auto a = std::array<int,50>{};
关于c++ - 为什么我更喜欢 "explicitly typed initializer"成语而不是明确给出类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25607216/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!