Not with GCC, but with Visual C++. It may concern 'typedef', and if so, it will be solved this way.
Topics
About: C++
The table of contents of this article
- Starting Context
- Target Context
- Orientation
- Main Body
- 1: Meeting a Mysterious "unable to match function definition to an existing declaration" Compile Error, Only with Visual C++
- 2: The Reason?
- 3: A Solution
Starting Context
- The reader has a basic knowledge on C++, even if he or she doesn't accurately understand its some widely-misrepresented elements.
Target Context
- The reader will know how to solve an "unable to match function definition to an existing declaration" Visual C++ error that concerns 'typedef'.
Orientation
A standard-map-compatible elements-order-preserved map has been created in an article.
The reality of C++ template has been examined in an article.
Main Body
1: Meeting a Mysterious "unable to match function definition to an existing declaration" Compile Error, Only with Visual C++
Hypothesizer 7
This (an excerpt from a standard-map-compatible elements-order-preserved map) is compiled fine with GCC, but not with Visual C++.
'theBiasPlanet/coreUtilities/collections/NavigableLinkedMap.hpp'
@C++ Source Code
#ifndef __theBiasPlanet_coreUtilities_collections_NavigableLinkedMap_hpp__
#define __theBiasPlanet_coreUtilities_collections_NavigableLinkedMap_hpp__
using namespace ::std;
namespace theBiasPlanet {
namespace coreUtilities {
namespace collections {
template <typename T, typename U, typename W = less <T>> class NavigableLinkedMap {
public:
typedef T key_type;
typedef U mapped_type;
typedef W key_compare;
public:
typedef pair <key_type const, mapped_type> value_type;
class BaseIterator {
};
class NonConstantIterator : public BaseIterator {
public:
typedef pair <key_type const, mapped_type> value_type;
virtual value_type & operator * ();
};
class ConstantIterator : public BaseIterator {
public:
typedef pair <key_type const, mapped_type> const value_type;
virtual value_type & operator * ();
};
};
}
}
}
#endif
'theBiasPlanet/coreUtilities/collections/NavigableLinkedMap.cpp'
@C++ Source Code
#include "theBiasPlanet/coreUtilities/collections/NavigableLinkedMap.hpp"
namespace theBiasPlanet {
namespace coreUtilities {
namespace collections {
template <typename T, typename U, typename W> typename NavigableLinkedMap <T, U, W>::NonConstantIterator::value_type & NavigableLinkedMap <T, U, W>::NonConstantIterator::operator * () {
// Omitted
}
template <typename T, typename U, typename W> typename NavigableLinkedMap <T, U, W>::ConstantIterator::value_type & NavigableLinkedMap <T, U, W>::ConstantIterator::operator * () {
// Omitted
}
}
}
}
The error mentions "template <typename T, typename U, typename W> typename NavigableLinkedMap <T, U, W>::ConstantIterator::value_type & NavigableLinkedMap <T, U, W>::ConstantIterator::operator * ()" and says that it is "unable to match function definition to an existing declaration" . . .
Note that the almost the same method, "template <typename T, typename U, typename W> typename NavigableLinkedMap <T, U, W>::NonConstantIterator::value_type & NavigableLinkedMap <T, U, W>::NonConstantIterator::operator * ()", is accepted all right. . . . Huh?
2: The Reason?
Hypothesizer 7
The only difference of the flagged one from the accepted one looks to be the name, "ConstantIterator", instead of "NonConstantIterator".
Well, is that specific name a kind of a trap? Should I change the name?
That, of course, is not the case.
Considering reasonably, the cause cannot be but the inside of "ConstantIterator::value_type". In fact, what else can it be?
It has turned out that the last "const" in "typedef pair <key_type const, mapped_type> const value_type" in the header file is the cause.
But why? What is wrong with it? . . . Honestly, I do not know.
If the "const" was eliminated in the header file and the return type in the 'cpp' file is changed to "typename NavigableLinkedMap <T, U, W>::ConstantIterator::value_type const &", the code would compile fine. Hmm . . .
But I cannot change the declaration of 'ConstantIterator::value_type', because it is a published type!. If it was changed, the compatibility with '::std::map' would be broken.
As the conclusion, I do not understand the reason, but I know the part that is causing the error.
3: A Solution
Hypothesizer 7
Well, my reasoning is that I cannot change the declaration of "ConstantIterator::value_type", so, I cannot help but not use it in the source file.
So, I have added a type, 'NonConstantvalue_type', as 'typedef pair <key_type const, mapped_type>', and changed the expression of the return type in the 'cpp' file to 'typename NavigableLinkedMap <T, U, W>::ConstantIterator::NonConstantvalue_type const &', which does not really change the return type. . . . Does that work fine? Yes.
Honestly, I am not happy about having to have such an extra otherwise-there-is-no-reason-to-exist type, but that is the best solution I have conceived of.