Damien T
Damien T

Reputation: 379

Template specialization works fine with gcc but not with visual studio 10

I have this template specialization in my code that works perfectly fine when I compile it with gcc but doesn't when I compile it using Visual Studio 10's compiler :

Field.cpp

template<>
void Field<std::string>::setValueString(const std::string &val)
{
  operator=(val);
}

template<>
void Field<bool>::setValueString(const std::string &val)
{
  bool v = static_cast<bool>(atoi(val.c_str()));
  operator=(v);
}

template<>
void Field<int32_t>::setValueString(const std::string &val)
{
  int intv = atoi(val.c_str());
  operator=(intv);
}

template<>
void Field<int16_t>::setValueString(const std::string &val)
{
  int intv = atoi(val.c_str());
  operator=(intv);
}

Field.hpp

template<typename FieldType>
class Field : public FieldBase
{
public:
  Field(const std::string &fieldName)
    : FieldBase(fieldName), _overriddenInsertValue(this) {}
  ~Field() {}

  (...)

  /**
   * @brief Template specialized for every available field type in Model.cpp
   */
  void setValueString(const std::string &)
  {
    ALT_ERROR("Field::setValueString called with wrong argument type.");
  }
};

On windows for some reason I always end up in the error case but I don't understand why, since it works fine when I run it on linux/mac os using gcc.

Upvotes: 1

Views: 773

Answers (2)

AnT stands with Russia
AnT stands with Russia

Reputation: 320381

If you want to define your template specializations in .cpp file, you still have to declare all of your template specializations in the header file

template<> void Field<std::string>::setValueString(const std::string &val);
template<> void Field<bool>::setValueString(const std::string &val);
template<> void Field<int32_t>::setValueString(const std::string &val);
template<> void Field<int16_t>::setValueString(const std::string &val);

The above declarations have to be present in the header file. I don't see them in your code.

You cannot just specialize the templates in some .cpp file and then expect the compiler to somehow magically know about it in all other translation units. This is what the declarations in the header file are for.

Upvotes: 3

Raxvan
Raxvan

Reputation: 6505

I think that to properly specialize the implementation of the functions from Field.cpp you need to declare the functions first in Field.hpp.

To specialize for a type you need something like this:

template<>
class Field <int32_t> : public FieldBase
{
public:
  ... rest of the functions
  void setValueString(const std::string &);
};

Hope this helps, Raxvan.

Upvotes: 0

Related Questions