编译器奇怪地试图调用另一个函数(构造函数)而非预期

时间:2015-01-03 05:49:50

标签: c++11 constructor initializer-list function-calls

HIHO,

我在C ++中实现了一个单例类,它在构造函数中初始化时出现问题,我尝试使用自定义构造函数初始化成员,但编译器认为我想调用默认构造函数(不带参数)和(当然)找不到它,因为我不需要该类的默认构造函数。

以下是代码:

class CionTokenTypes final {
private:
    CionTokenTypes();

    TokenType init_tt(TokenType token_type, bool skipped = false);

    std::vector<TokenType> m_all_token_types;
    std::vector<TokenType> m_skipped_token_types;

    static const CionTokenTypes c_instance;

public:
    CionTokenTypes(CionTokenTypes const&) = delete;
    CionTokenTypes(CionTokenTypes &&) = delete;

    static CionTokenTypes const& get_instance();

    std::vector<TokenType> const& get_all() const;
    std::vector<TokenType> const& get_skipped() const;

    TokenType const my_custom_token_type;
};

这是源文件:

const CionTokenTypes CionTokenTypes::c_instance = {};

TokenType CionTokenTypes::init_tt(
    TokenType token_type,
    bool skipped
) {
    m_all_token_types.push_back(token_type);
    if (skipped) {
        m_skipped_token_types.push_back(token_type);
    }
    return std::move(token_type);
}

CionTokenTypes const& CionTokenTypes::get_instance() {
    return c_instance;
}

std::vector<TokenType> const& CionTokenTypes::get_all() const {
    return m_all_token_types;
}

std::vector<TokenType> const& CionTokenTypes::get_skipped() const {
    return m_skipped_token_types;
}

CionTokenTypes::CionTokenTypes():
    m_all_token_types{},
    m_skipped_token_types{},
    my_custom_token_type{init_tt({"bracket: closing bracket ]", "\\]"})}
{}

您可能还想查看TokenType类:

class TokenType final {
public:
    enum class MatchType : uint8_t {
        non_greedy,
        greedy
    };

    TokenType(
        std::string const& name,
        std::string const& regex = "",
        TokenTypeStore store_type = TokenTypeStore::empty,
        MatchType match_type = MatchType::non_greedy);

    TokenType() = delete;
    TokenType(TokenType const& other) = default;
    TokenType(TokenType && other) = default;
    TokenType & operator=(TokenType const& other) = default;
    TokenType & operator=(TokenType && other) = default;
};

及其源文件:

TokenType::TokenType(
    std::string const& name,
    std::string const& regex,
    TokenTypeStore store_type,
    TokenType::MatchType match_type
):
    m_data{
        std::make_shared<TokenType::Data>(
            name,
            regex,
            store_type,
            match_type
        )
    }
{}

我已经删除了不重要的部分,因为这些文件对于StackOverflow上的完整粘贴来说太大了。

编译错误:

/home/robbepop/coding/c++/projects/cion/src/token/cion_token_types.cpp: In constructor ‘cion::CionTokenTypes::CionTokenTypes()’:
/home/robbepop/coding/c++/projects/cion/src/token/cion_token_types.cpp:207:69: error: use of deleted function ‘cion::TokenType::TokenType()’
   closing_brack  {init_tt({"bracket: closing bracket ]"    , "\\]"})}
                                                                     ^
In file included from /home/robbepop/coding/c++/projects/cion/include/token/cion_token_types.hpp:4:0,
                 from /home/robbepop/coding/c++/projects/cion/src/token/cion_token_types.cpp:1:
/home/robbepop/coding/c++/projects/cion/include/token/token_type.hpp:56:3: note: declared here
   TokenType() = delete;
   ^
/home/robbepop/coding/c++/projects/cion/src/token/cion_token_types.cpp:207:69: error: use of deleted function ‘cion::TokenType::TokenType()’
   closing_brack  {init_tt({"bracket: closing bracket ]"    , "\\]"})}
                                                                     ^
In file included from /home/robbepop/coding/c++/projects/cion/include/token/cion_token_types.hpp:4:0,
                 from /home/robbepop/coding/c++/projects/cion/src/token/cion_token_types.cpp:1:
/home/robbepop/coding/c++/projects/cion/include/token/token_type.hpp:56:3: note: declared here
   TokenType() = delete;
   ^
src/CMakeFiles/cion_compiler.dir/build.make:1066: recipe for target 'src/CMakeFiles/cion_compiler.dir/token/cion_token_types.cpp.o' failed
make[2]: *** [src/CMakeFiles/cion_compiler.dir/token/cion_token_types.cpp.o] Error 1
CMakeFiles/Makefile2:75: recipe for target 'src/CMakeFiles/cion_compiler.dir/all' failed
make[1]: *** [src/CMakeFiles/cion_compiler.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2
make  62.10s user 5.93s system 98% cpu 1:08.80 total

我希望你能帮助我,因为我真的不知道为什么编译器认为我想调用默认构造函数而不是我的自定义构造函数...

我终于发现了这个奇怪的编译器错误的来源:

事实上,这真的很奇怪。问题的根源是头文件声明了CionTokenTypes类的大约一百个成员,但是它们以错误的顺序初始化,有些甚至被遗漏在类的源文件中,这导致了编译器可能出错的错误找到最后一个成员的默认构造函数。

所以我觉得这种混乱主要是由于这种情况的错误处理不当造成的。

1 个答案:

答案 0 :(得分:0)

可能是错的,因为我似乎没有足够的代码来正确重现ideone中的错误。

从您在第210行尝试调用TokenType的默认构造函数的事物来看,因为编译器没有自动生成,所以会出错。它没有生成,因为你已经声明了另一个构造函数,然后C ++的规则跳过了默认构造函数的生成。

解决方案包括(其中之一):

  1. 您不应该调用默认构造函数,因此请调查第210行并停止它。
  2. 您确实想要一个默认构造函数,将行TokenType() = default;添加到您的TokenType结构中。