-2

Hiho,

I have implemented a singleton class in C++ which has got a problem with an initialization within its constructor where I try to initialize a member with a custom constructor but instead the compiler thinks I want to call the default constructor (without arguments) and (of course) can't find it as I don't need a default constructor for that class.

Here is the code:

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

Here is the source file:

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 ]", "\\]"})}
{}

And you might also want to see the TokenType class:

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

And its source file:

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
        )
    }
{}

I have cut out the not important parts as these files would have been just too huge for a complete paste at StackOverflow.

The compiler error:

/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

I hope you can help me as I really don't know why the compiler thinks that I want to call the default constructor instead of my custom one ...

I finally found out what's the source of this strange compiler error:

It is in fact really strange. The source of the problem was that the header file declared about one hundred members of the CionTokenTypes class but they got initialized in the wrong order and some got even left out in the source file of the class which resulted in the error that the compiler can't find the default constructor for the last member.

So I guess this confusing was mainly caused by a poor error handling for this situation.

Cœur
  • 37,241
  • 25
  • 195
  • 267
robbepop
  • 119
  • 10
  • it is okay if it is huge put the whole thing, it will help in better understanding your problem. – Ganesh Kamath - 'Code Frenzy' Jan 03 '15 at 05:57
  • Which compiler and which version? Also, the code in your posted errors does not seem to match the code you posted. – T.C. Jan 03 '15 at 05:58
  • GCC 4.9.x was used. Is it also okay to provide a link to a gist at github for you guys? – robbepop Jan 03 '15 at 06:03
  • Next time please provide a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). The code you provided is neither complete enough to compile nor stripped of irrelevant pieces. Reducing the problem to its smallest size is both a great way to identify your own problem and to help others help you. – Mark Jan 03 '15 at 10:29
  • As I have only a vague understanding where the error actually does come from I can not provide you with a minimal or a verifiable example code. I'll create a github of my project and provide you with the link to it if this is allowed on StackoverFlow. – robbepop Jan 03 '15 at 12:50
  • The easiest way to produce the MCVE is to just remove stuff until you get either no errors or a different error (which you can often fix by removing yet more stufF). Anyway, sure, throw up a link to github or ideone. Removing helper functions and other cruft is a great place to start. – Mark Jan 03 '15 at 19:16
  • yeah that's actually how I finally found the source of the bug - I edited my initial post for the solution. thanks! – robbepop Jan 03 '15 at 21:16

1 Answers1

0

Could be wrong, as I do not seem to have enough of your code to properly reproduce the error in ideone.

From the looks of things your are attempting to invoke the default constructor of TokenType at line 210 and because none is being automatically generated by the compiler, you get an error. It is not being generated because you have declared another constructor and the rules of C++ then skip generation of the default constructor.

Solutions include (one of):

  1. You weren't supposed to be calling a default constructor, so investigate line 210 and stop that.
  2. You actually did want a default constructor, add the line TokenType() = default; to your TokenType struct.
Mark
  • 3,806
  • 3
  • 21
  • 32
  • Side note: You also seem to have asked for default generation of the move assignment operator but *not* the move constructor. This strikes me as strange. You might also consider adding the line `TokenType(TokenType&&) = default;` – Mark Jan 03 '15 at 10:22
  • Thanks for your answer, however, you don't seem to fully understand or read my question as I have stated that I do not wish to call the default constructor on line 210. Instead I call the line: my_custom_token_type{init_tt({"bracket: closing bracket ]", "\\]"})} And the compiler somehow thinks I want to call the default constructor which is confusing me because I obviously have stated at least one parameter (the init_tt thingy). I have changed the code above in order to make it more clear. – robbepop Jan 03 '15 at 12:54