The following code compiles just fine under Visual Studio but neither gcc 4.6.2 or 4.7 can handle it. It seems to be valid but gcc can't seem to resolve the difference between const and non const parameters. Could this be a compiler bug?
struct CReadType{};
struct CWriteType{};
template<typename ReadWriteType, typename T>
struct AddPkgrConstByType {};
template<typename T>
struct AddPkgrConstByType<CReadType, T> {
typedef T type;
};
template<typename T>
struct AddPkgrConstByType<CReadType, const T> {
typedef T type;
};
template<typename T>
struct AddPkgrConstByType<CWriteType, T> {
typedef T const type;
};
template<typename Packager, typename T>
struct AddPkgrConst : public AddPkgrConstByType<typename Packager::CReadWriteType, T> {
};
template<typename Packager, typename T>
inline bool Package( Packager* ppkgr, T* pt )
{
return true;
}
template<typename Packager>
inline bool Package( Packager* ppkgr, typename AddPkgrConst<Packager,bool>::type* pb)
{
return false;
}
struct ReadPackager {
typedef CReadType CReadWriteType;
};
struct WritePackager {
typedef CWriteType CReadWriteType;
};
int main(int argc, char* argv[])
{
ReadPackager rp;
WritePackager wp;
bool b = true;
const bool cb = false;
Package( &rp, &b );
}
Compiler call:
g++ -fPIC -O -std=c++0x -Wno-deprecated -D_REENTRANT
g++-D__STDC_LIMIT_MACROS -c test.cpp
test.cpp: In function ‘int main(int, char**)’:
test.cpp:58:22: error: call of overloaded ‘Package(ReadPackager*, bool*)’ is ambiguous
test.cpp:58:22: note: candidates are:
test.cpp:31:6: note: bool Package(Packager*, T*) [with Packager = ReadPackager, T = bool]
test.cpp:38:6: note: bool Package(Packager*, typename AddPkgrConst<Packager, bool>::type*) [with Packager = ReadPackager, typename AddPkgrConst<Packager, bool>::type = bool]
I don't know what's wrong with Visual Studio, but what
gccsays seems right:You instantiate
AddPkgrConstByType<CReadType, T>becausePackager::CReadWriteTyperesolves toCReadType. Therefore,AddPkgrConst<Packager,bool>::typewill resolve according to the first implementation (which is not a specialisation) tobool. This means you have two separate function specialisations with the same parameter list, which C++ doesn't allow you.