gpt4 book ai didi

C++ 我应该使用模板,我即将创建一个词法分析器,为什么它应该是有限的字符?

转载 作者:搜寻专家 更新时间:2023-10-31 00:15:47 25 4
gpt4 key购买 nike

关闭。这个问题需要details or clarity .它目前不接受答案。












想改进这个问题?通过 editing this post 添加详细信息并澄清问题.

8年前关闭。




Improve this question




我即将为一个项目创建一个词法分析器,证明它的概念存在,这个想法有效等等,我正要开始写它,我意识到:

为什么是字符?

(我正在远离 C,我仍然对标准库持怀疑态度,我觉得处理 char* 用于偏移等比了解字符串更容易)

为什么不使用 w_char 或其他东西、整数或任何类型(假设它有一些已定义的操作)。

那么我应该使用模板吗?到目前为止,我似乎应该是的,但我可以考虑两个相反的论点:

首先,模块化的复杂性,当我编写"template"时,它必须放在头文件中/可以用于任何使用它的实现(这不是隐藏源代码的问题,我不介意必须显示代码部分,它将是免费的(如自由)软件)这意味着额外的解析和类似的事情。

我的C背景尖叫着不要这样做,我似乎想要单独的.o文件,顺便说一句,我明白为什么我不能,我不是在寻求方法。
单独的目标文件会加速复杂化,因为 make 文件(你告诉它或让它使用 -MM 和编译器自行确定)不会为未更改的事物运行复杂化命令等等。

其次,对于模板,我知道没有办法指定类型必须做什么,除了让用户意识到什么时候失败(你知道 Java 如何有一个 extends 关键字)我怀疑 C++11 建立在此之上,作为元-programming 是《C++ 编程语言》第 4 版中的一个大章节。

这些天来这些理由重要吗?我学到了以下内容:
“您不是在创建一个可以编译的巨大代码文件,而是创建了链接的小文件”,而模板似乎与此背道而驰。

我确信 G++ 解析速度非常快,但它也进行了优化,如果它花费大量时间优化一个文件,它会在每次在翻译单元中看到它时重新进行优化,与单独的目标文件一样,它只做了一次(一般优化),如果您使用 LTO(链接时间优化),可能会做更多

或者我可以创建一个类,词法分析器的每个输入都来自并使用它(我相信它被称为通用编程),但我的 C 根说“eww virtuals”并敦促我使用 char*

我知道这是非常开放的,我只是不知道在使用模板和不使用模板之间划清界限。

最佳答案

模板不必在标题中!如果您只有几个实例化,您可以在合适的翻译单元中显式实例化类和函数模板。也就是说,模板将分为三个部分:

  • 声明模板的 header 。
  • 包含第一个和实现模板的标题,但仅包含在第三组文件中。
  • 源文件,包括 2. 中的 header ,并显式实例化具有相应类型的模板。

  • 这些模板的用户只会包含 header ,而不会包含实现 header 。可以做到这一点的一个例子是 IOStreams:基本上只有两个实例化:一个用于 char。一个用于 wchar_t .是的,您可以实例化其他类型的流,但我怀疑是否有人会这样做(我有时会质疑是否有人使用与 char 不同的字符类型的流,但可能人们会这样做)。

    也就是说,模板使用的概念确实没有在源代码中明确表示,C++11 也没有添加任何工具来这样做。有关于向 C++ 添加概念的讨论,但到目前为止它们还不是任何标准的一部分。我认为有一个概念轻量级提案将包含在 C++14 中。

    然而,在实践中我并没有发现太大的问题:很可能记录概念并使用像 static_assert() 这样的东西。可能会产生更好的错误消息。问题在于许多概念实际上比底层算法更具限制性,而且额外的松弛有时非常有用。

    这是一个关于如何实现和实例化模板的简短且有些虚构的示例。这个想法是实现类似 std::basic_ostream但仅提供字符串输出运算符的缩小版本:
    // simple-ostream.hpp
    #include "simple-streambuf.hpp"
    template <typename CT>
    class simple_ostream {
    simple_streambuf<CT>* d_sbuf;
    public:
    simple_ostream(simple_streambuf<CT>* sbuf);
    simple_streambuf<CT>* rdbuf() { return this->d_sbuf; } // should be inline
    };
    template <typename CT>
    simple_ostream<CT>& operator<< (simple_ostream<CT>&, CT const*);

    除了 rdbuf()上面的成员只是一个带有一些成员声明和一个函数声明的类定义。 rdbuf()函数是直接实现的,以表明您可以将需要性能的可见实现与解耦更重要的外部实现混合和匹配。使用的类模板 simple_streambuf被认为类似于 std::basic_streambuf并且至少在标题 "simple-streambuf.hpp" 中声明.
    // simple-ostream.tpp
    // the implementation, only included to create explicit instantiations
    #include "simple-ostream.hpp"

    template <typename CT>
    simple_ostream<CT>::simple_ostream(simple_streambuf<CT>* sbuf): d_sbuf(sbuf) {}

    template <typename CT>
    simple_ostream<CT>& operator<< (simple_ostream<CT>& out, CT const* str) {
    for (; *str; ++str) {
    out.rdbuf()->sputc(*str);
    }
    return out;
    }

    仅在显式实例化类和函数模板时才包含此实现 header 。例如, char 的实例化看起来像这样:
    // simple-ostream-char.cpp
    #include "simple-ostream.tpp"

    // instantiate all class members for simple_ostream<char>:
    template class simple_ostream<char>;
    // instantiate the free-standing operator
    template simple_ostream<char>& operator<< <char>(simple_ostream<char>&, char const*);

    任何使用 simple_ostream<CT>只包括 simple-ostream.hpp .例如:
    // use-simple-ostream.cpp
    #include "simple-ostream.hpp"

    int main()
    {
    simple_streambuf<char> sbuf;
    simple_ostream<char> out(&sbuf);
    out << "hello, world\n";
    }

    当然,要构建可执行文件,您将需要两个 use-simple-ostream.osimple-ostream-char.o但是假设模板实例是库的一部分,这并没有真正增加任何复杂性。唯一真正令人头疼的是当用户想要使用具有意外实例化的类模板时,例如 char16_t , 但仅限 charwchar_t提供:在这种情况下,用户需要显式创建实例化,或者,如果需要,包括实现 header 。

    如果你想试试这个例子,下面是一个有点简单和草率(因为只是标题)的 simple-streambuf<CT> 实现。 :
    #ifndef INCLUDED_SIMPLE_STREAMBUF
    #define INCLUDED_SIMPLE_STREAMBUF
    #include <iostream>

    template <typename CT> struct stream;
    template <>
    struct stream<char> {
    static std::ostream& get() { return std::cout; }
    };
    template <>
    struct stream<wchar_t> {
    static std::wostream& get() { return std::wcout; }
    };

    template <typename CT>
    struct simple_streambuf
    {
    void sputc(CT c) {
    stream<CT>::get().rdbuf()->sputc(c);
    }
    };

    #endif

    关于C++ 我应该使用模板,我即将创建一个词法分析器,为什么它应该是有限的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18477554/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com