具有多个模板参数的 class 中 operator[] 的模板特化
Template specialization of operator[] within a class with multiple template parameters
我在专门化使用 2 个模板参数声明的分词器 class 的 2 个方法时遇到问题。我已经引用了 Template specialization of a single method from a templated class,但我在实施过程中仍然遇到一些错误。一些代码(EOF 附近的专用函数):
#pragma once
#include "stdafx.h"
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
inline const std::string emptyString = "";
inline const std::wstring emptyWString = L"";
template <class stringT = std::string, class delimiterT = char>
class Tokenizer
{
private:
std::vector<stringT> tokens;
bool enableParserThrow;
public:
Tokenizer(bool throwOnParseError) : enableParserThrow(throwOnParseError)
{
}
Tokenizer(const stringT& tokenizeMe, delimiterT delimiter) : Tokenizer(true)
{
TokenizeString(tokenizeMe, delimiter);
}
void TokenizeString(const stringT& str, delimiterT delimiter)
{
std::stringstream ss;
ss << str;
std::string token;
while (std::getline(ss, token, delimiter))
{
tokens.push_back(token);
}
}
template <class T>
T ParseToken(size_t tokenIndex)
{
if (tokenIndex < 0 || tokenIndex >= tokens.size())
{
ThrowParserExceptionIfEnabled("Index out of range.");
return T();
}
T temp;
std::stringstream ss;
ss << tokens[tokenIndex];
ss >> temp;
if (ss.fail())
ThrowParserExceptionIfEnabled("Parse failure.");
return temp;
}
void Clear()
{
tokens.clear();
}
const std::vector<stringT>& GetTokens()
{
return tokens;
}
void ThrowParserExceptionIfEnabled(const char* message)
{
if (enableParserThrow)
{
throw std::runtime_exception(message);
}
}
// Trying to specialize these functions so I can return a reference to a global empty std::string or std::wstring if tokeIndex is out of range
template<>
const std::string& Tokenizer<std::string, delimiterT>::operator[](size_t tokenIndex);
//TODO:
//template<>
//const std::string& Tokenizer<std::wstring, delimiterT>::operator[](size_t tokenIndex);
};
template<class stringT, class delimiterT>
inline const std::string & Tokenizer<stringT, delimiterT>::operator[](size_t tokenIndex)
{
return emptyString;
}
Tokenizer<>::operator[] 的正确专业化定义是什么?
我在实施过程中收到以下错误:
由于您的 operator[]
不是模板,因此您无法在 class 中专门化它。您想要的是专门针对模板 class.
的非模板方法
但是您不能对 class 进行部分特化以向其添加成员定义。
工作示例:
template <class stringT = std::string, class delimiterT = char>
class Tokenizer
{
const std::string& operator[](size_t tokenIndex);
};
template<>
inline const std::string& Tokenizer<std::wstring, char>::operator[](size_t )
{
return emptyString;
}
template< >
inline const std::string& Tokenizer<std::string, char>::operator[](size_t )
{
return emptyString;
}
要解决这个问题,您应该检查您的方法是否真的依赖于所有模板参数。如果没有,您可以简单地将它们放在一个基 class 中,它只依赖于一个模板参数并从那里继承。也许其他代码组织也有帮助。
我在专门化使用 2 个模板参数声明的分词器 class 的 2 个方法时遇到问题。我已经引用了 Template specialization of a single method from a templated class,但我在实施过程中仍然遇到一些错误。一些代码(EOF 附近的专用函数):
#pragma once
#include "stdafx.h"
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
inline const std::string emptyString = "";
inline const std::wstring emptyWString = L"";
template <class stringT = std::string, class delimiterT = char>
class Tokenizer
{
private:
std::vector<stringT> tokens;
bool enableParserThrow;
public:
Tokenizer(bool throwOnParseError) : enableParserThrow(throwOnParseError)
{
}
Tokenizer(const stringT& tokenizeMe, delimiterT delimiter) : Tokenizer(true)
{
TokenizeString(tokenizeMe, delimiter);
}
void TokenizeString(const stringT& str, delimiterT delimiter)
{
std::stringstream ss;
ss << str;
std::string token;
while (std::getline(ss, token, delimiter))
{
tokens.push_back(token);
}
}
template <class T>
T ParseToken(size_t tokenIndex)
{
if (tokenIndex < 0 || tokenIndex >= tokens.size())
{
ThrowParserExceptionIfEnabled("Index out of range.");
return T();
}
T temp;
std::stringstream ss;
ss << tokens[tokenIndex];
ss >> temp;
if (ss.fail())
ThrowParserExceptionIfEnabled("Parse failure.");
return temp;
}
void Clear()
{
tokens.clear();
}
const std::vector<stringT>& GetTokens()
{
return tokens;
}
void ThrowParserExceptionIfEnabled(const char* message)
{
if (enableParserThrow)
{
throw std::runtime_exception(message);
}
}
// Trying to specialize these functions so I can return a reference to a global empty std::string or std::wstring if tokeIndex is out of range
template<>
const std::string& Tokenizer<std::string, delimiterT>::operator[](size_t tokenIndex);
//TODO:
//template<>
//const std::string& Tokenizer<std::wstring, delimiterT>::operator[](size_t tokenIndex);
};
template<class stringT, class delimiterT>
inline const std::string & Tokenizer<stringT, delimiterT>::operator[](size_t tokenIndex)
{
return emptyString;
}
Tokenizer<>::operator[] 的正确专业化定义是什么?
我在实施过程中收到以下错误:
由于您的 operator[]
不是模板,因此您无法在 class 中专门化它。您想要的是专门针对模板 class.
但是您不能对 class 进行部分特化以向其添加成员定义。
工作示例:
template <class stringT = std::string, class delimiterT = char>
class Tokenizer
{
const std::string& operator[](size_t tokenIndex);
};
template<>
inline const std::string& Tokenizer<std::wstring, char>::operator[](size_t )
{
return emptyString;
}
template< >
inline const std::string& Tokenizer<std::string, char>::operator[](size_t )
{
return emptyString;
}
要解决这个问题,您应该检查您的方法是否真的依赖于所有模板参数。如果没有,您可以简单地将它们放在一个基 class 中,它只依赖于一个模板参数并从那里继承。也许其他代码组织也有帮助。