I'm having trouble specializing 2 methods of a tokenizer class that's declared with 2 template parameters. I've referenced Template specialization of a single method from a templated class but I am still encountering a few errors with my implementation. Some code (specialized functions near 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;
}
What is the proper specialization definition of Tokenizer<>::operator[]?
I'm receiving the following errors with this implementation:
CodePudding user response:
As your operator[]
is not a template, you can't specialize it inside your class. What you want is to specialize the non template method for a template class.
But you can't do a partial specialization for the class to add definitions of members to it.
Working example:
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;
}
To get rid of that problem you should check if your method really depends on all template parameters. If not, you can simply put them to a base class, which only depends on a single template parm and inherit from there. Maybe other code organization may also help.