构造函数委托中的C ++调用函数

时间:2014-08-07 05:16:45

标签: c++ c++11 constructor initialization-list

在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])使它工作,任何想法为什么?

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;
}

回答原始问题FWIW


为什么不尝试?

除非你调用一个使用仍然未初始化的成员的函数,否则应该没有问题。

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;
}