在c ++ 11中,构造函数可以转发到初始化列表中的另一个构造函数。
可以在初始化列表中调用函数,就像在此question
中一样在构造函数委托中调用函数也没问题吗?
我尝试了这样的代码:
#include <iostream>
#include <string>
#include <yaml-cpp/yaml.h>
using namespace std;
YAML::Node ParseFromFile(const string& filepath) {
YAML::Node yaml;
try {
return YAML::LoadFile(filepath);
} catch(const YAML::BadFile& e) {
cout << "error";
}
}
class A {
public:
A(YAML::Node yaml) {
cout << "Got" << endl;
}
A(const string& filepath) : A(ParseFromFile(filepath)) {}
};
int main(int argc, char** argv) {
A a(string(argv[1]));
YAML::Node yaml = ParseFromFile(string(argv[1]));
A b(yaml);
return 0;
}
对于上面的代码,只需将一个空文件传递给它,它只会在初始化b期间打印一个“Got”。
=============================================== ========================
用argv [1]替换字符串(argv [1])使它工作,任何想法为什么?
答案 0 :(得分:3)
问题是main中的第一行被视为函数声明而不是变量初始化,实际上你用clang编译它会给你一个警告:
警告:括号被消除歧义为函数声明
这是由于标准中的§6.8模糊度解析中定义的内容(AKA Most vexing parse)(强调我的......):
涉及表达式语句的语法含糊不清 和声明:具有函数样式的表达式语句 显式类型转换(5.2.3),因为它最左边的子表达式可以 与第一个声明者开始的声明无法区分 a(。在这些情况下,声明是声明。
考虑以下示例:
#include <iostream>
#include <string>
#include <exception>
using namespace std;
struct A{
string a;
A(string s) : a(s){ cout<< "Ctor" <<endl;}
A(int i) : A(to_string(i)){ }
};
void foo (A (*a)(string*)){
cout<<"yay"<<endl;
}
int main(int argc, char** argv) {
A a1( string(argv[1]) ); // function A a1(std::string*) declaration not a variable
/* ^ ^ ^
| | |
return type name arg type
Same as foo
*/
// foo(a1);// <- compiles but fails only due to linkage
A a2 = A(string(argv[1])); // works
A a3{string(argv[1])}; // works
A a4(string{argv[1]}); // works
A a5( ( string(argv[1]) ) ); // works allso but confusing imho
/* ^ ^
notice extra paren. | |
*/
return 0;
}
为什么不尝试?
除非你调用一个使用仍然未初始化的成员的函数,否则应该没有问题。
E.g(demo):
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(string x) {
cout << "Got " << x << endl;
}
A(int x) : A(std::to_string(x)) {}
};
int main() {
A a(15);
return 0;
}