Gcc4 template error or id10t error probability

The following code compiles simply in Visual Studio, but neither gcc 4.6.2 nor 4.7 can handle it. It seems valid, but gcc does not seem to be able to solve the difference between constant and non-constant parameters. Could this be a compiler error?

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]
+5
source share
3 answers

This seems like a compiler error. This is about overload resolution and partial ordering of template functions. Since both template functions can correspond to an argument list (ReadPackager*, bool), a partial ordering of template functions should be used to select a more specialized template function.

, , , , , .

, Package(), , , (ReadPackager *, const int *) . , -, , .

, , , - . , .

-, P1 P2 .

1:

template<typename Packager, typename T>
bool Package( Packager* ppkgr, T* pt );

P2:

template<typename Packager>
bool Package( Packager* ppkgr, typename AddPkgrConst<Packager,bool>::type* pb);

, (T1) , , (T2). , (T1) , (T2). P2- > P1

  • U Packager P2.
  • P1. Packager U T AddPkgrConst<Packager,U>::type.

, P1 , P2.

P1- > P2:

  • U1 U2 Packager T P1, (U1 *, U2 *).
  • P2. Packager U1.
  • , , , .
  • , AddPkgrConst<U1,bool>::type, bool. U2.

, 4. , , , 4 , P2 , P1, , . , P1 , P2 , . , , .

, 1 14.8.2.5,

, , ( P), ( A), ( , - ), P ( A), .

AddPkgrConst<U1,bool>::type= bool. A, U2. , -, , .

+4

, Visual Studio, gcc, :

AddPkgrConstByType<CReadType, T>, Packager::CReadWriteType CReadType. , AddPkgrConst<Packager,bool>::type ( ) bool. , , ++ .

+3

, . bool* , g++.

, , . , .

template <typename Packager, typename T>
struct Wrapper
{
    static bool Package()
    {
        return true;
    }
};

template <typename Packager>
struct Wrapper<Packager, typename AddPkgrConst<Packager,bool>::type>
{
    static bool Package()
    {
        return false;
    }
};

template <typename Packager, typename T>
Wrapper<Packager, T> make_wrapper(Packager* /*p*/, T* /*t*/)
{
    return Wrapper<Packager, T>();
}

int main()
{
    ReadPackager rp;
    bool b = true;
    std::cout << make_wrapper(&rp, &b).Package() << std::endl;  // Prints out 0.
}
+1

All Articles