【问题标题】:Had to specify upper limit while evaluating the length of C-style string through template metaprogramming在通过模板元编程评估 C 风格字符串的长度时必须指定上限
【发布时间】:2016-08-01 02:13:25
【问题描述】:

我最近开始在 C++ 中使用模板元编程,并尝试评估 C 风格字符串的长度。

我在这段代码上取得了一些成功

template <const char *str, std::size_t index>
class str_length {
public:
    static inline std::size_t val() {
        return (str[index] != '\0') ? (1 + str_length<str, index + 1>::val()) :             0;
    }
};

template <const char *str>
class str_length <str, 500> {
public:
    static inline std::size_t val() {
        return 0;
    }
};

extern const char bitarr[] { "0000000000000000000" };

int main() {
    std::cout << str_length<bitarr, 0>::val() << std::endl;

    getchar();
    return 0;
}

但是,我必须通过创建 str_length 的特化来设置 500 的“上限”。忽略它会导致我的编译器无限期运行(可能会创建 str_length 的无限特化)。

有什么办法可以不指定 index = 500 限制吗? 如果有帮助,我正在使用 VC++2015。

哦,我没有使用 constexpr,因为 VC++ 还不完全支持 C++14 扩展的 constexpr 功能。 (https://msdn.microsoft.com/en-us/library/hh567368.aspx#cpp14table)

【问题讨论】:

  • 你为什么不使用 bitarr 是一个 array 并因此已经具有编译时大小的事实?
  • 正如我所说,只是在玩 TMP。
  • @NicolBolas 在数组末尾可能有 '\0'。不太可能,但可能。

标签: c++ template-meta-programming


【解决方案1】:

在这种情况下,停止无限模板实例化的常用方法是使用特化;这与任何事物的constexpr-ness 正交。查看在 C++14 中扩展 constexpr 允许的其他内容列表,我在以下示例中看不到任何需要扩展 constexpr 支持的内容。 gcc 6.1.1 在-std=c++11 合规模式下编译它,FWIW:

#include <iostream>

template<const char *str, size_t index, char c> class str_length_helper;

template <const char *str>
class str_length {
public:

    static constexpr std::size_t val()
    {
        return str_length_helper<str, 0, str[0]>::val();
    }
};

template<const char *str, std::size_t index, char c>
class str_length_helper {

public:

    static constexpr std::size_t val()
    {
        return 1+str_length_helper<str, index+1, str[index+1]>::val();
    }
};

template<const char *str, std::size_t index>
class str_length_helper<str, index, 0> {
public:

    static constexpr std::size_t val()
    {
        return 0;
    }
};

static constexpr char bitarr[] { "0000000000000000000" };

int main() {
    std::cout << str_length<bitarr>::val() << std::endl;

    getchar();
    return 0;
}

但是请注意,字符串本身必须是constexpr。正如 cmets 所指出的,这在实际用途中是可疑的;但是为了掌握元编程的窍门,以这种方式胡闹并没有错。

关键是使用特化,为了能够使用str[index]作为模板参数,str必须是constexpr

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
  • 2013-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多