开发者

Template Error: no appropriate default constructor available

开发者 https://www.devze.com 2023-02-15 17:30 出处:网络
The thing is, I am not (knowing trying to use any default constructor of beatle::beatle the error: 1>ecosystem.cpp

The thing is, I am not (knowing trying to use any default constructor of beatle::beatle the error:

1>  ecosystem.cpp
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\map(172): error C2512: 'beatle::beatle' : no appropriate default constructor available
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\map(165) : while compiling class template member function 'beatle &std::map<_Kty,_Ty>::operator [](int &&)'
1>          with
1>          [
1>              _Kty=tokenID,
1>              _Ty=beatle
1>          ]
1>          c:\users\zak\documents\visual studio 2010\projects\ascii_sivvure\ascii_sivvure\ecosystem.h(22) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
1>          with
1>          [
1>              _Kty=tokenID,
1>              _Ty=beatle
1>          ]

Code with non relevant things stripped:

header:

typedef std::map<tokenID,beatle>    Beatles;

class ecosystem
{
private:
line 22:    Beatles m_Beatles;
};

source:

ecosystem::ecosystem(): m_output( output() )
{
    Beatles m_Beatles;
}

void ecosystem::populate()
{
    if (m_isMatingSeason && ( random(0,1000) < rateMATING ) )
    {
        beatle babyBeatle = breed();
        m_Beatles[babyBeatle.getTokenID()] = babyBeatle;
        m_field.occupy(babyBeatle.getTokenID(), babyBeatle.getLocation() );
    }
}

I've been trying for hours using different combinations of trying to properly define/declare the maps. At one point intellisense starti开发者_StackOverflowng saying it wanted pointers to object here:

m_Beatles[babyBeatle.getTokenID()] = babyBeatle;

and that led me down a sad path.

This is all happening after my first(and hopefully last) refactoring binge, its been over a week since I've been able to compile... I probably have 40 hours just trying to get it working again.


std::map<>::operator[] requires a default constructor. This is because it first creates an entry in the map then does the operator= that you are calling.

If you absolutely want to use an std::map but do not want to provide a default constructor (perhaps it is illogical for your case?) you can use:

std::map<>::insert()

To explicitly insert the object into the code. This makes things a bit more complicated then because look ups must also use find.

I just noticed that Adam Rosenfield already posted this info in a comment but going ahead and leaving this as a separate answer.


Does the beatle class have a default constructor? Using operator[] on a std::map can construct an entry in the map if one isn't found with the key you give, and so it needs to be able to create map values (here, beatle).


With correction prompted by Adam Rosenfield's comment...

std::map<>::operator[] requires the value type to have a public default constructor: you simply must have one in class beatle if you want to use that function from std::map<>. The Standard says it's ok to create containers of non-default-constructible objects as long as you don't call member functions with signatures specifying default constructed arguments (see below), but this doesn't actually gel with the std::map<>::operator[] issue which uses T() despite not mentioning it in the signature.

20.1.4 - Default construction [lib.default.con.req]

-1- The default constructor is not required. Certain container class member function signatures specify the default constructor as a default argument. T() must be a well-defined expression (dcl.init) if one of those signatures is called using the default argument (dcl.fct.default).

You ask if that means you can leave the member variables uninitialised in your default constructor. Yes, as long as they're not say pointers that may be deleted by operator= or the destructor - you'd need to explicitly set them to 0/NULL. If some member variables are objects with their own default constructors, these could be run whether you need them to be or not (i.e. even if they're just setting ints, doubles etc.) unless the compiler-time optimisations are able to detect that they're redundant.

0

精彩评论

暂无评论...
验证码 换一张
取 消