【问题标题】:Weird "candidate expects 1 argument, 0 provided" in constructor构造函数中奇怪的“候选人需要 1 个参数,提供 0 个参数”
【发布时间】:2012-02-11 03:43:09
【问题描述】:

我正在用 C++ 制作一个简单的线程服务器应用程序,事情是,我使用 libconfig++ 来解析我的配置文件。好吧,libconfig 不支持多线程,因此我使用两个包装类来完成“支持”。关键是,其中一个失败了:

class app_config {
    friend class app_config_lock;
public:
    app_config(char *file) :
        cfg(new libconfig::Config()),
        mutex(new boost::mutex())
    {
        cfg->readFile(file);
    }

private:
    boost::shared_ptr<libconfig::Config> cfg;
    boost::shared_ptr<boost::mutex> mutex;
};

从我的 main.cpp 文件中调用时会严重失败:

app_main::app_main(int c, char **v) : argc(c), argv(v) {
    // here need code to parse arguments and pass configuration file!.
    try {
        config = app_config("mscs.cfg");
    } catch (libconfig::ParseException &e) {
        cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl;
        throw;
    } catch (libconfig::FileIOException &e) {
        cout << "Configuration file not found." << endl;
        throw;
    }
}

它说:

main.cpp: In constructor ‘app_main::app_main(int, char**)’:
main.cpp:38:54: error: no matching function for call to ‘app_config::app_config()’
main.cpp:38:54: note: candidates are:
../include/app_config.h:15:5: note: app_config::app_config(char*)
../include/app_config.h:15:5: note:   candidate expects 1 argument, 0 provided
../include/app_config.h:12:7: note: app_config::app_config(const app_config&)
../include/app_config.h:12:7: note:   candidate expects 1 argument, 0 provided
main.cpp:41:39: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] (THIS CAN BE IGNORED, I WAS USING STD::STRING, YET CHANGED IT FOR TESTING PURPOSES)

这很奇怪,因为我显然在传递一个参数,而且它是一个 char *!。

嗯,一如既往,我们将不胜感激。

朱利安。

【问题讨论】:

    标签: c++ exception-handling construction member-variables function-try-block


    【解决方案1】:

    您正在尝试默认构造您的配置,然后再分配给它。但是你没有默认构造函数。

    将参数传递给成员变量的构造函数的正确方法是:

    app_main::app_main(int c, char **v) : argc(c), argv(v), config("mscs.cfg")
    

    您仍然可以通过使用所谓的 function try-block 来捕获异常。见http://www.gotw.ca/gotw/066.htm

    最终代码:

    app_main::app_main(int c, char **v)
    try : argc(c), argv(v), config("mscs.cfg")
    {
        // more constructor logic here
    } catch (libconfig::ParseException &e) {
        cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl;
        throw;
    } catch (libconfig::FileIOException &e) {
        cout << "Configuration file not found." << endl;
        throw;
    }
    

    【讨论】:

    • 这解决了问题。但是,我计划传递一个变量字符串,而不是静态字符串,有什么方法可以在我的 app_main 成员中实际处理我的 argc 和 argv 变量并在此之后初始化配置,而不是在初始化列表中?
    • @JulianBayardoSpadafora:不。您可以将构造函数的参数传递给成员构造函数,而不仅仅是编译时常量。您也可以在 ctor-initializer-list 中调用静态成员函数。最后,您可以控制成员的构建顺序。但是您可能需要在此之前进行参数处理,并通过getConfigFilename() 或此类成员函数传入某种选项捆绑对象。或者干脆给app_config一个函数来读取文件,而不是从构造函数中读取。
    【解决方案2】:

    首先,不要动态分配互斥体,它没有任何用处。其次,这是因为您有一个无法默认构造的数据成员,并且您没有在 ctor init 列表中对其进行初始化。另外,永远不要将字符串文字分配给 char* 变量(如果你真的想涉足 char 指针,它应该是 app_config(const char*))。

    您的 app_main::app_main 应该是这样的:

    app_main::app_main(int c, char **v) try
        : argc(c), argv(v), config("mscs.cfg") {
    } catch (libconfig::ParseException &e) {
        cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl;
        throw;
    } catch (libconfig::FileIOException &e) {
        cout << "Configuration file not found." << endl;
        throw;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-11-22
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 2022-09-24
      • 2016-01-10
      • 1970-01-01
      • 2020-04-11
      • 1970-01-01
      相关资源
      最近更新 更多