简体   繁体   English

在通过模板元编程评估C风格字符串的长度时,必须指定上限

[英]Had to specify upper limit while evaluating the length of C-style string through template metaprogramming

I recently starting playing around with template metaprogramming in C++, and been trying to evaluate the length of a C-style string. 我最近开始在C ++中使用模板元编程,并一直在尝试评估C风格字符串的长度。

I've had some success with this bit of code 这段代码我取得了一些成功

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

However, I had to set a "upper limit" of 500 by creating a specialization of str_length. 但是,我必须通过创建str_length的特化来设置500的“上限”。 Omitting that would cause my compiler to run indefinitely (presumably creating infinite specializations of str_length). 省略这会导致我的编译器无限期地运行(可能会创建str_length的无限特化)。

Is there anything I could do to not specify the index = 500 limit? 我有什么办法可以不指定index = 500的限制吗? I'm using VC++2015 if that helps. 如果有帮助,我正在使用VC ++ 2015。

Oh, and I'm not using constexpr because VC++ doesn't quite support the C++14 extended constexpr features yet. 哦,我没有使用constexpr,因为VC ++还不太支持C ++ 14扩展的constexpr功能。 ( https://msdn.microsoft.com/en-us/library/hh567368.aspx#cpp14table ) https://msdn.microsoft.com/en-us/library/hh567368.aspx#cpp14table

The usual way to stop infinite template instantiation, in these situation, is by using specialization; 在这种情况下,停止无限模板实例化的常用方法是使用专门化; which is orthogonal to constexpr -ness of anything. 这与任何东西的constexpr都是正交的。 Reviewing the list of additional stuff that extended constexpr allows in C++14, I see nothing in the following example that needs extended constexpr support. 回顾一下扩展constexpr在C ++ 14中允许的其他内容列表,我在以下示例中看不到任何需要扩展constexpr支持的内容。 gcc 6.1.1 compiles this in -std=c++11 compliance mode, FWIW: gcc 6.1.1在-std=c++11-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;
}

Note, however, that the character string itself must be constexpr . 但请注意,字符串本身必须是constexpr As the comments noted, this is of dubious practical use; 正如评论所指出的那样,这是可疑的实际用途; but there's nothing wrong with messing around in this manner in order to get the hang of metaprogramming. 但是以这种方式搞乱是为了获得元编程的悬念并没有错。

The key point is the use of specialization, and the fact that in order to be able to use str[index] as a template parameter, str must be constexpr . 关键点是使用特化,以及为了能够使用str[index]作为模板参数, str必须是constexpr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM