jignatius
jignatius

Reputation: 6504

Invalid use of incomplete type for class with std::map<int, T> member

I am trying to write a template class using SFINAE to convert from a map to json and vice versa. The idea is to restrict the class to maps that have an integral value type or convertible to int, i.e. enums, but I'm having problems compiling my class.

Here's my code so far:

MapToJsonConvertor.h:

#ifndef COMMON_MAPTOJSONCONVERTOR_H_
#define COMMON_MAPTOJSONCONVERTOR_H_

#include <Poco/JSON/Object.h>
#include <Poco/JSON/Parser.h>
#include <Poco/Dynamic/Var.h>
#include <Poco/JSON/Stringifier.h>
#include <map>
#include <type_traits>


template<typename T,
    typename = typename std::enable_if<std::is_convertible<T, int>::value, T>::type>
class MapToJsonConvertor
{
public:
    MapToJsonConvertor(const std::map<int, T> &mapFrom): mMap(mapFrom)
    {}
    MapToJsonConvertor(const Poco::JSON::Object::Ptr &jsonObject): mJsonObject(jsonObject)
    {}
    Poco::JSON::Object::Ptr Convert(const std::string &rootName);
    //std::map<int, T> Convert(const Poco::JSON::Object::Ptr &jsonObject);

private:
    std::map<int, T> mMap;
    Poco::JSON::Object::Ptr mJsonObject;
};


#endif /* COMMON_MAPTOJSONCONVERTER_H_ */

MapToJsonConvertor.cpp

#include "MapToJsonConvertor.h"

template<typename T>
Poco::JSON::Object::Ptr MapToJsonConvertor<T>::Convert(const std::string &rootName)
{
    Poco::JSON::Object::Ptr root = new Poco::JSON::Object();
    Poco::JSON::Array::Ptr array = new Poco::JSON::Array();

    if (!mMap.empty())
    {
        for (auto &elem : mMap)
        {
            Poco::JSON::Object::Ptr elemPtr = new Poco::JSON::Object();
            elemPtr->set("key", elem.first);
            elemPtr->set("value", static_cast<int>(elem.second));
            array->add(elemPtr);
        }
    }

    root->set("elements", array);

    return root;
}

The error I get is:

../src/Common/MapToJsonConvertor.cpp:12:83: error: invalid use of incomplete type ‘class MapToJsonConvertor<T>’ Poco::JSON::Object::Ptr MapToJsonConvertor<T>::Convert(const std::string &rootName)
^
In file included from ../src/Common/MapToJsonConvertor.cpp:9:0: ../src/Common/MapToJsonConvertor.h:21:7: note: declaration of ‘class MapToJsonConvertor<T>’ class MapToJsonConvertor ^

I'm using the Poco libraries for Json building.

I'm still new to template metaprogramming with SFINAE, so I would appreciate some help. What am I doing wrong?

Upvotes: 0

Views: 222

Answers (1)

Timo
Timo

Reputation: 9835

So first of all, templates should be implemented in the header file as explained here.

Besides that, your problem lies in the template signature of your function definition in your source file. You are using a 2nd template parameter in your class for SFINAE so you have to specify that template parameter in the definition as well:

template<typename T, typename U> // note the 2nd parameter
Poco::JSON::Object::Ptr MapToJsonConvertor<T, U>::Convert(const std::string &rootName)
{
    ...
}

Upvotes: 1

Related Questions