【问题标题】:Unpack parameter pack into string view将参数包解包到字符串视图中
【发布时间】:2017-11-05 21:09:19
【问题描述】:

可以将 char 类型的值模板参数包解压缩为(编译时)字符串。 如何将string_view 获取到该字符串中?

我想做什么:

int main()
    {
    constexpr auto s = stringify<'a', 'b', 'c'>();
    constexpr std::string_view sv{ s.begin(), s.size() };
    return 0;
    }

试试:

template<char ... chars>
constexpr auto stringify()
    {
    std::array<char, sizeof...(chars)> array = { chars... };
    return array;
    }

错误:

15 : <source>:15:30: error: constexpr variable 'sv' must be initialized by a constant expression
constexpr std::string_view sv{ s.begin(), s.size() };
                         ^~~~~~~~~~~~~~~~~~~~~~~~~
15 : <source>:15:30: note: pointer to subobject of 's' is not a constant expression

有没有办法获得main 函数中的行为?

【问题讨论】:

    标签: c++ variadic-templates c++17 string-view


    【解决方案1】:

    它不能作为 constexpr 工作,因为 s 数组位于堆栈上,因此在编译时它的地址是未知的。要修复,您可以将s 声明为static

    Check this solution in online compiler

    【讨论】:

    • 那为什么编译得很好呢? constexpr const char* myData = "hello"; constexpr std::string_view sv(myData); myData 也是堆栈上的一个变量,但它可以工作
    • @Valentin 在这种情况下,数据存储在字符串字面量 "hello" 的全局分配数组中,只有指向该数组的指针存储在堆栈中。
    • 这是有道理的。但是,constexpr std::array s {'a', 'b'};std::array s {'a', 'b'}; 有何不同?如果无论如何都不能使用,将其定义为 constexpr 有什么好处?为什么允许?
    • @Valentin 只要你不需要堆栈上的地址就可以正常工作,例如你可以constexpr auto avg{(s[0] + s[1]) / 2};
    • 非常感谢。这绝对是我遇到的最困难的问题之一。
    【解决方案2】:

    这段代码在 clang 中编译,尽管 GCC 仍然抛出一个(我认为不正确的)错误:

    #include <iostream>
    #include <array>
    #include <string_view>
    
    template<char... chars>
    struct stringify {
        // you can still just get a view with the size, but this way it's a valid c-string
        static constexpr std::array<char, sizeof...(chars) + 1> str = { chars..., '\0' };
        static constexpr std::string_view str_view{&str[0]};
    };
    
    int main() {
        std::cout << stringify<'a','b','c'>::str_view;
        return 0;
    }
    

    虽然它会生成有关“子对象”的警告。 (字符...)另一个答案解释了它起作用的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多