【问题标题】:Template specialization of operator[] within a class with multiple template parameters具有多个模板参数的类中 operator[] 的模板特化
【发布时间】:2022-01-21 19:02:00
【问题描述】:

我无法专门化使用 2 个模板参数声明的标记器类的 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[] 的正确专业化定义是什么?

我收到以下关于此实现的错误:

【问题讨论】:

  • 请分享您收到的错误消息。
  • 似乎我的问题是封闭式思维链接问题stackoverflow.com/questions/495021/… 回答了这篇文章。不幸的是,它没有。
  • 如前所述,您需要添加收到的错误消息。
  • 对不起,我已经更新了我的实现,直接在头文件中内联了专门的方法。我还附上了我遇到的错误的屏幕截图。
  • 错误消息是文本。请不要发布指向文本信息图像的链接。将文本复制并粘贴为文本。

标签: c++ templates template-specialization


【解决方案1】:

由于您的operator[] 不是模板,因此您不能在您的班级中专门处理它。您想要的是专门化模板类的非模板方法。

但是您不能对类进行部分特化以向其添加成员定义。

工作示例:

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;
}

要摆脱这个问题,您应该检查您的方法是否真的依赖于所有模板参数。如果没有,您可以简单地将它们放到一个基类中,该基类仅依赖于单个模板参数并从那里继承。也许其他代码组织也可能有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2012-09-29
    • 1970-01-01
    • 2011-12-14
    • 2014-09-16
    相关资源
    最近更新 更多