包含头文件和源文件的部分和完整模板专业化(Partial and full template specialization with header and source files)
有人可以帮助我重构下面的代码,以便它编译(使用pre-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 declarationCould someone please help me refactor the following code so that it compiles (with a pre-C++11 compiler).
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 } }I believe the compilation error is because full specialization has to be defined at namespace scope, rather than inside the class definition. Beyond this I am lost.
EDIT: The error message is (roughly) as follows:
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最满意答案
首先,你在错误信息中有答案:明确的专门化必须在命名空间范围内:
把你的标题变成这样:
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<>不用于专业化的成员,所以在cpp文件中省略它
The following worked for me:
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更多推荐
发布评论