user2836797
user2836797

Reputation:

Why is the compiler not seeing the default parameter value specified?

Observe the following interface/implementation:

properties.h

class Property
{
  public:
    Property(PropertyCollection * propertyCollection, std::string key, 
      std::string value, uint32_t identifier);

properties.cpp

Property::Property(PropertyCollection * propertyCollection, 
  std::string key, std::string value, uint32_t identifier = 0)
  : propertyCollection(propertyCollection), key(key), value(value), 
    identifier(identifier) {}

As you can see, I have a default initializer for the last argument.

However, I still get this Eclipse error:

main.cpp

Properties properties (*file);
Property property (&properties, std::string("Cats"), std::string("Rule"));

no matching function for call to ‘Property::Property(Properties*, std::string, std::string)’

EDIT: Properties inherits from PropertyCollection. PropertyCollection is a pure virtual class.

 +----------------------+
 |    <<pure virtual>>  |
 | PropertyCollection   |
 +----------------------+
 |                      |
 +----------------------+
             ^
             |
             +
+-----------------------+
| Properties            |
|-----------------------|
|                       |
+-----------------------+

In Java I'd think of Properties *as a * PropertyCollection and just pass the reference as-is. However, in C++, must I cast the pointer to the base class somehow?

Edit: Guess not. The sole problem was the location of the default initializer.

Upvotes: 4

Views: 68

Answers (4)

R Sahu
R Sahu

Reputation: 206607

The solution has already provided in a the answer by juanchopanza. I'm going to present how the .h file and the .cpp file should look after the change.

properties.h

class Property
{
  public:
    Property(PropertyCollection * propertyCollection, std::string key, 
      std::string value, uint32_t identifier = 0);

properties.cpp

Property::Property(PropertyCollection * propertyCollection, 
  std::string key, std::string value, uint32_t identifier)
  : propertyCollection(propertyCollection), key(key), value(value), 
    identifier(identifier) {}

Upvotes: 1

juanchopanza
juanchopanza

Reputation: 227418

You need to put the default parameter in the member function declaration, i.e. in the header file, not in its definition:

class Property
{
  public:
    Property(PropertyCollection * propertyCollection, std::string key, 
      std::string value, uint32_t identifier = 0);

In the code you've shown, main can only see Property::Property(PropertyCollection*, std::string, std::string, uint32_t).

Upvotes: 1

Filip Ros&#233;en
Filip Ros&#233;en

Reputation: 63797

The why

It seems as if you are including properties.h from your main source code and later link against what is inside properties.cpp, which is totally fine in trivial cases.

But when doing what you are doing there's no way for the compiler to know (at time of compiling main) that the constructor you are trying to invoke has a default parameter (this isn't know until you are linking against properties.cpp).

In main the compiler only knows what you have told it, more specifically it only knows about

Property::Property (PropertyCollection * propertyCollection, std::string key, 
  std::string value, uint32_t identifier);

The solution

The simple, and recommended, solution is to move the default-value specification to the constructor declaration in properties.h, this way the compiler will have all the information required to make things work the way you intend.


Upvotes: 4

yizzlez
yizzlez

Reputation: 8805

In the constructor:

Property(PropertyCollection * propertyCollection, std::string key, std::string value);

Your constructor:

Property(Property * propertyCollection, std::string key, std::string value);

Pass an address of an object of PropertyCollection, or create new constructor.

Upvotes: 0

Related Questions