使用大括号实例化 - 它是什么,为什么在这里使用它?



最近我偶然发现了这篇关于如何在现代C++中导入dll库的文章。代码完全让我不知所措,所以我一行一行地浏览它并试图弄清楚它的含义。到目前为止,我想我明白了,但有一件事我仍然不清楚:

class ShellApi {
DllHelper _dll{"Shell32.dll"};
/* ... */
};
class DllHelper {
public:
explicit DllHelper(LPCTSTR filename) : _module(LoadLibrary(filename)) {}    
/* ... */
private:
HMODULE _module;
};

为什么实例化DllHelper _dll{"Shell32.dll"}用大括号而不是普通括号编写?我在Visual Studio中尝试了一下,不得不意识到这个片段不适用于普通括号。为什么不呢?这种实例化是如何调用的(以便我稍后可以查找(?是否还有其他使用此功能的方案?

如果我提供的代码不足以回答问题,则整个代码可在文章中找到。

List初始化自C++11以来就存在,通常被视为当今初始化对象的实际方式(除了一些特殊情况(:

std::string s{"foo"};  // Initialize the std::string s with "foo"

列表初始化和直接初始化之间存在差异,这些差异在 https://en.cppreference.com/w/cpp/language/list_initialization 上进行了总结,其中一些是:

  • 列表初始化不允许缩小转换范围:
int f();
char c1(f()); // Ok
char c2{f()}; // error: narrowing conversion from int to char
  • 列表初始化可防止您进行最烦人的解析:
struct X { };
X x1(X()); // x1 is a function
X x2{X{}}; // x2 is a X
  • 在您的情况下,列表初始化用于默认初始化ShellApi的非静态成员,并且您不能使用()来初始化它:
struct X {
int a1{1};   // Ok
int a2 = 1;  // Ok
int a3(1);   // Nok
int b{};  // Ok, b is an int member default-initialized to 0
int b();  // Ok, b is a member-function returning an int
};

最新更新