具有多个模板参数的 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 中,它只依赖于一个模板参数并从那里继承。也许其他代码组织也有帮助。