【问题标题】:Length of user-defined string literal as a template argument?用户定义的字符串文字的长度作为模板参数?
【发布时间】:2013-06-22 15:54:02
【问题描述】:

有没有办法得到这样的行为?

// Some definition(s) of operator "" _my_str
// Some definition of function or macro MY_STR_LEN

using T1 = MY_STR_LEN("ape"_my_str);
// T1 is std::integral_constant<std::size_t, 3U>.

using T2 = MY_STR_LEN("aardvark"_my_str);
// T2 is std::integral_constant<std::size_t, 8U>.

似乎不是,因为字符串文字会立即传递给some_return_type operator "" _my_str(const char*, std::size_t);,而永远不会传递给文字运算符模板(2.14.8/5)。该大小函数参数不能用作模板参数,即使它几乎总是一个常量表达式。

但似乎应该有某种方法可以做到这一点。


更新:接受的答案是,如果没有每个文字的额外定义,这是不可能的,对于 C++11 以及 C++14 和 C++17 来说都是准确的。 C++20 允许要求的确切结果:

#include <cstdlib>
#include <type_traits>
#include <string_view>

struct cexpr_str {
    const char* ptr;
    std::size_t len;

    template <std::size_t Len>
    constexpr cexpr_str(const char (&str)[Len]) noexcept
    : ptr(str), len(Len) {}
};

// Essentially the same as
// std::literals::string_view_literals::operator""sv :
template <cexpr_str Str>
constexpr std::string_view operator "" _my_str () noexcept
{
     return std::string_view(Str.ptr, Str.len);
}

#define MY_STR_LEN(sv) \
  std::integral_constant<std::size_t, (sv).size()>

【问题讨论】:

    标签: c++11 generic-programming user-defined-literals


    【解决方案1】:

    仔细阅读 C++11 2.14.8 会发现“文字运算符模板”仅适用于数字文字,而不适用于字符串和字符文字。

    但是,以下方法似乎可以让您通过 constexpr 访问字符串长度(但不是指针):

    struct MyStr
    {
        char const * str;
        unsigned int len;
        constexpr MyStr(char const * p, unsigned int n) : str(p), len(n) {}
    };
    
    constexpr MyStr operator "" _xyz (char const * s, unsigned int len)
    {
        return MyStr(s, len);
    }
    
    constexpr auto s = "Hello"_xyz;
    

    测试:

    #include <array>
    
    using atype = std::array<int, s.len>; // OK
    

    【讨论】:

    • 是的,但这仅适用于一个特定对象s。所以我们需要为每个用户定义的文字命名?
    • 我也无法锻炼myTemplate&lt;len_here&gt; operator"" _test(char const * s, unsigned int len)。
    • @MooingDuck:你是什么意思?正如我所说,对于字符串文字,长度只能作为动态参数使用,而不是作为常量表达式,所以我认为你不能在长度上参数化模板......
    猜你喜欢
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 2010-10-25
    • 2018-05-12
    • 2014-08-05
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多