【问题标题】:Template integer parameter constructor模板整数参数构造函数
【发布时间】:2014-02-04 12:47:44
【问题描述】:

我不明白以下构造函数(src\corelib\tools\qstringbuilder.h 中 Qt 库的一部分),它是什么意思,它是如何工作的?

class QLatin1Literal
{
public:
    int size() const { return m_size; }
    const char *data() const { return m_data; }

    template <int N>
    QLatin1Literal(const char (&str)[N])
        : m_size(N - 1), m_data(str) {}

private:
    const int m_size;
    const char * const m_data;
};

【问题讨论】:

  • N 这里是一个非类型模板参数。

标签: c++ templates


【解决方案1】:

构造函数将字符串文字作为参数。您看到的只是为此声明模板的语法。

使用这样的构造函数 m_size 可以在 O(1) 中找到,而不是 O(strlen(str)),否则需要使用以 char const* 作为参数的非模板构造函数。

要记住的是,对于每个字符串长度,编译器都会生成一个模板实例,因此您最终可能会在库/二进制/目标文件中拥有该模板的很多实例。

【讨论】:

  • +1,但我想说这些“实例化”实际上是内联的,并且从未真正将其作为独立的二进制文件。
  • @Andrew - 同意,内联影响只会稍微增加编译时间,而不是二进制大小。
  • 这里要记住的另一件重要的事情是由于特殊的大小写,当存在const char* 重载时,将选择一个而不是模板一个,即使它似乎是一个更好的匹配(不需要衰减)。
【解决方案2】:

构造函数参数是对N 字符数组的引用。它将m_data 初始化为指向第一个字符,并将m_size 初始化为比数组大小小一个。

字符串文字,如@9​​87654324@,是一个字符数组,包含字符串中的字符,后跟一个零值终止符。因此,如果使用以下之一调用构造函数:

 QLatin1Literal lit("hello");
 assert(lit.size() == strlen("hello"));  // SUCCESS: m_size is inferred as 5

它会推断N 的值为6(因为数组包含“hello”的五个字符,加上终止符),并将m_size 初始化为5(实际字符串长度)。

请注意,如果数组实际上不是字符串文字,这可能会出错;例如:

char buffer[1000] = "hello";  // array size is larger than string+terminator
QLatin1Literal lit(buffer);
assert(lit.size() == strlen("hello"));  // FAIL: m_size is inferred as 999

【讨论】:

    【解决方案3】:

    这意味着str 是对N 常量字符数组的引用。它只是意味着构造函数将一个字符数组作为参数,例如字符串文字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 2016-09-02
      • 2019-01-29
      • 2023-01-30
      • 1970-01-01
      相关资源
      最近更新 更多