dimanche 2 août 2015

A piece of code cannot be compiled by intel compiler but clang will compile it

The following code is a minimum working (or perhaps non-working) example.

What it does is basically that it encapsulates a bunch of std::map structures as private members in a base class. To avoid writing a lot of setters and getters, they are implemented as template functions.

//  test.cpp

#include <map>
#include <iostream>    

enum class E0
{
    F0, F1, F2,
};       

The declaration of the base class.

using std::map; 
class P_base
{
private:
    map<E0, int> m_imap;
    //  ...
    //  ... Other std::map members with different key types and value types.
public:
    map<E0, int> & imap;    
    //  ...
    //  ... Other std::map references.

    P_base() : imap(m_imap) {}    

    template<typename map_type, typename key_type, typename val_type>
    void set(map_type & m, const key_type & k, const val_type & v)
    {
        m[k] = v;
    }    

    template<typename map_type, typename key_type>
    auto access_to_map(const map_type & m, const key_type & k) -> decltype(m.at(k))
    {
        return m.at(k);
    }
};    

class P : private P_base
{
public:
    decltype(P_base::imap) & imap;    

    P() : P_base(), imap(P_base::imap) {}    

    template<typename map_type, typename key_type, typename val_type>
    void set(map_type & m, const key_type & k, const val_type & v)
    {
        P_base::set(m, k, v);
    }    

    template<typename map_type, typename key_type>
    auto access_to_map(const map_type & m, const key_type & k) -> decltype(P_base::access_to_map(m, k))
    {
        return P_base::access_to_map(m, k);
    }
};    

main

int main(int argc, const char * argv[])
{
    using std::cout;
    using std::endl;    

    P op;    

    op.set(op.imap, E0::F0, 100);
    op.set(op.imap, E0::F1, 101);
    op.set(op.imap, E0::F2, 102);    

    cout << op.access_to_map(op.imap, E0::F1) << endl;

}


$ clang++ -std=c++11 test.cpp && ./a.out
101

But if I compile it with intel compiler (icpc version 15.0.3 (gcc version 5.1.0 compatibility)), the compiler gives me this error message (which I don't undertand at all, especially when clang will compile the code):

$ icpc -std=c++ test.cpp && ./a.out
test.cpp(67): error: no instance of function template "P::access_to_map" matches the argument list
        argument types are: (std::__1::map<E0, int, std::__1::less<E0>, std::__1::allocator<std::__1::pair<const E0, int>>>, E0)
        object type is: P
  cout << op.access_to_map(op.imap, E0::F1) << endl;

And it also confuses me by not complaining about the set function.

Does anyone have any idea what is going on here?

Thanks.

Aucun commentaire:

Enregistrer un commentaire