具有头文件和源文件的部分和完整模板专业化

时间:2017-03-02 20:49:43

标签: c++ templates

有人可以帮我重构以下代码,以便编译(使用前C ++ 11编译器)。

MyClass.h:

namespace myns {
enum LiteralTypes {
  kINT_LITERAL = 0,
  kSTRING_LITERAL
};

class MyClass {
  template <LiteralTypes literal_type, typename T> struct AddLiterals;

  template <typename T>
  struct AddLiterals<kINT_LITERAL, T> {
    static void apply(const vector<T>& vals);
  };

  template <>
  struct AddLiterals<kSTRING_LITERAL, char*> {
    static void apply(const vector<char*>& vals);
  };


  template <>
  struct AddLiterals<kSTRING_LITERAL, std::string> {
    static void apply(const vector<std::string>& vals);
  };
};
}

MyClass.cpp

namespace myns {
template <typename T>
void MyClass::AddLiterals<kINT_LITERAL, T>::apply(const vector<T>& vals) {
  BOOST_STATIC_ASSERT((boost::is_same<T, int16_t>::value ||
                       boost::is_same<T, int32_t>::value ||
                       boost::is_same<T, int64_t>::value));
  // Implementation
}

template <>
void MyClass::AddLiterals<kINT_LITERAL, char*>::apply(const vector<char*>& vals) {
  // Implementation
}

template <>
void MyClass::AddLiterals<kINT_LITERAL, std::string>::apply(const vector<std::string>& vals) {
  // Implementation
}
}

我认为编译错误是因为必须在命名空间范围内定义完全特化,而不是在类定义中定义。除此之外,我迷失了。

编辑: 错误消息(大致)如下:

MyClass.h: error: explicit specialization in non-namespace scope ‘class myns::MyClass’
MyClass.cpp: error: template-id ‘apply<>’ for ‘void myns::MyClass::AddLiterals<kSTRING_LITERAL, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::apply(const vector<std::string>& vals)’ does not match any template declaration
MyClass.cpp: error: invalid function declaration

2 个答案:

答案 0 :(得分:1)

首先,您的错误消息中有答案:显式特化必须在命名空间范围内:

将标题转换为:

namespace myns {
enum LiteralTypes {
  kINT_LITERAL = 0,
  kSTRING_LITERAL
};

class MyClass {
  template <LiteralTypes literal_type, typename T> struct AddLiterals;
};

  template <typename T>
  struct MyClass::AddLiterals<kINT_LITERAL, T> {
    static void apply(const vector<T>& vals);
  };

  template <>
  struct MyClass::AddLiterals<kSTRING_LITERAL, char*> {
    static void apply(const vector<char*>& vals);
  };


  template <>
  struct MyClass::AddLiterals<kSTRING_LITERAL, std::string> {
    static void apply(const vector<std::string>& vals);
  };
}

其次,你有一个不匹配,请注意你在声明中使用了2d和3d特化与kSTRING_LITERAL,但在定义中使用了kINT_LITERAL

第三,template<>未用于specialization的成员,因此在cpp文件中省略它

答案 1 :(得分:1)

以下对我有用:

MyClass.h:

namespace myns {
enum LiteralTypes {
  kINT_LITERAL = 0,
  kSTRING_LITERAL
};

class MyClass {
  template <LiteralTypes literal_type, typename T> struct AddLiterals;

  template <typename T>
  struct AddLiterals<kINT_LITERAL, T> {
    static void apply(const vector<T>& vals);
  };

  template <typename T>
  struct AddLiterals<kSTRING_LITERAL, T> {
    static void apply(const vector<T>& vals);
  };
};
}

MyClass.cpp

namespace myns {
template <typename T>
void MyClass::AddLiterals<kINT_LITERAL, T>::apply(const vector<T>& vals) {
  BOOST_STATIC_ASSERT((boost::is_same<T, int16_t>::value ||
                       boost::is_same<T, int32_t>::value ||
                       boost::is_same<T, int64_t>::value));
  // Implementation
}

template <>
void MyClass::AddLiterals<kSTRING_LITERAL, char*>::apply(const vector<char*>& vals) {
  // Implementation
}

template <>
void MyClass::AddLiterals<kSTRING_LITERAL, std::string>::apply(const vector<std::string>& vals) {
  // Implementation
}
} // namespace myns