dependent-name is parsed as a non-type, but instantiation yields a type 에러 해결 방법

다음과 같은 코드를 작성했다.

template<typename T1, typename T2>
class ObjectMap
{
public:
    typedef boost::mutex                    Mutex;
    typedef boost::lock_guard<Mutex>      LockGuard;
    typedef std::map<T1, T2>              Map;

    bool InsertObject(T1& key, T2& object)
    {
        LockGuard lock(object_map_mutex_);
        auto result = object_map_.insert(Map::value_type(key, object));
        return result.second;
    }

대략 템플릿으로 std::map을 래핑해서 사용하려는 클래스인데 이 코드는 Visual Studio 2015 에서 아무 문제 없이 컴파일되며 실제로 작동상에도 아무 문제가 없는 코드이다.

하지만 이 코드를 gcc에서 컴파일 하려고 하면 다음과 같은 오류가 발생하며 컴파일 자체가 되질 않는다. 참 신기한 노릇… (컴파일러는 CentOS 7의 gcc 4.8.2 버전이다.)

/container/object_map.h:28:63: error: dependent-name ‘ObjectMap<T1, T2>::Map:: value_type’ is parsed as a non-type, but instantiation yields a type
   auto result = object_map_.insert(Map::value_type(key, object));
                                                               ^
/container/object_map.h:28:63: note: say ‘typename ObjectMap<T1, T2>::Map:: value_type’ if a type is meant

이 문제에 대해 한참을 찾아본 결과 다음의 주소에서 힌트를 얻을 수 있었다.

http://stackoverflow.com/questions/6021686/c-iterator-to-stdmap

원인은 해당하는 부분에 컴파일러가 타입을 알 수 없다는 얘기.

코드를 다음과 같이 바꾸어주었더니 gcc에서도 컴파일이 잘 된다.

auto result = object_map_.insert(typename Map::value_type(key, object));

예전에도 느꼈지만 리눅스에서 빌드하는거 참 귀찮고 어렵다는거 다시 한번 느낀다.

Leave a Reply

Your email address will not be published. Required fields are marked *