如何在构造函数的成员初始化列表中调用两个函数?
How can I call two functions in contructor's member initializer list?
我可以调用初始化列表中的函数吗?请看这段代码:
#include <string>
using namespace std;
class A {
public:
A(string path) : s(cfg.getRoot()) { // before i call getRoot, i need to call cfg.readFile(path.c_str()), is there any methods? (readFile return void)
}
private:
libconfig::Config cfg;
const libconfig::Setting & s; // const &, so initalizer list is the only chance for me to init it
}
你需要把它包装成一个函子,例如static
成员函数或 lambda (C++11 起):
A(string path) : s([this]() -> const libconfig::Setting &
{ cfg.readFile(path.c_str()); return cfg.getRoot(); }
()
)
{}
您还可以使用逗号运算符(尽管对于 reader 这可能会或可能不会更难理解):
A(string path) : s((cfg.readFile(path.c_str()), cfg.getRoot())) {}
内置逗号运算符从左到右计算并丢弃左侧表达式的结果。请注意,双括号是必需的。否则它将被解析为 s
构造函数的两个函数参数。
如果 cfg.readFile(path.c_str())
的 return 类型有重载的逗号运算符(但这种情况很少见),这将无法正常工作。在这种情况下,您需要将结果转换为 void
以丢弃 return 值:
A(string path) : s((static_cast<void>(cfg.readFile(path.c_str())), cfg.getRoot())) {}
已经给出了 lambda 方法。如果使用 decltype(auto)
:
可以避免重复 return 类型
A(string path) : s([this]()->decltype(auto){
cfg.readFile(path.c_str());
return cfg.getRoot();
}()) {}
这又是一个风格问题,无论您是否喜欢明确地给出 return 类型。
正如@songyuanyao 在下面的评论中指出的那样,如果您未指定 return 类型或适当的占位符,那么如果 cfg.getRoot
return 是引用,您将遇到麻烦,因为默认的 lambda 类型是一个 auto
占位符,这将导致从引用构造一个临时对象,然后您将绑定到 s
并将立即再次销毁。
我可以调用初始化列表中的函数吗?请看这段代码:
#include <string>
using namespace std;
class A {
public:
A(string path) : s(cfg.getRoot()) { // before i call getRoot, i need to call cfg.readFile(path.c_str()), is there any methods? (readFile return void)
}
private:
libconfig::Config cfg;
const libconfig::Setting & s; // const &, so initalizer list is the only chance for me to init it
}
你需要把它包装成一个函子,例如static
成员函数或 lambda (C++11 起):
A(string path) : s([this]() -> const libconfig::Setting &
{ cfg.readFile(path.c_str()); return cfg.getRoot(); }
()
)
{}
您还可以使用逗号运算符(尽管对于 reader 这可能会或可能不会更难理解):
A(string path) : s((cfg.readFile(path.c_str()), cfg.getRoot())) {}
内置逗号运算符从左到右计算并丢弃左侧表达式的结果。请注意,双括号是必需的。否则它将被解析为 s
构造函数的两个函数参数。
如果 cfg.readFile(path.c_str())
的 return 类型有重载的逗号运算符(但这种情况很少见),这将无法正常工作。在这种情况下,您需要将结果转换为 void
以丢弃 return 值:
A(string path) : s((static_cast<void>(cfg.readFile(path.c_str())), cfg.getRoot())) {}
已经给出了 lambda 方法。如果使用 decltype(auto)
:
A(string path) : s([this]()->decltype(auto){
cfg.readFile(path.c_str());
return cfg.getRoot();
}()) {}
这又是一个风格问题,无论您是否喜欢明确地给出 return 类型。
正如@songyuanyao 在下面的评论中指出的那样,如果您未指定 return 类型或适当的占位符,那么如果 cfg.getRoot
return 是引用,您将遇到麻烦,因为默认的 lambda 类型是一个 auto
占位符,这将导致从引用构造一个临时对象,然后您将绑定到 s
并将立即再次销毁。