【问题标题】:How to create boost::hana::map with keys being compile-time strings (C++14)?如何创建 boost::hana::map 的键是编译时字符串(C++14)?
【发布时间】:2018-07-10 09:32:18
【问题描述】:

我在 boost.hana 邮件列表中看到了以下示例,但无法编译:

#include <boost/hana.hpp>
#include <string>
namespace hana = boost::hana;
int main(int argc, char **argv) {

    constexpr auto m1 = hana::make_map(
            hana::make_pair("key1"_s, hana::type_c<std::string>),
            hana::make_pair("key2"_s, hana::type_c<std::string>)
        ); 
}

我在 GCC 7.3.0 -std=c++14 上收到以下错误:

error: unable to find string literal operator ‘operator""_s’ with ‘const char [5]’, ‘long unsigned int’ arguments
             hana::make_pair("key1"_s, hana::type_c<std::string>),
                             ^~~~~~~~

顺便问一下,字符串字面量的«_s»后缀是什么?

【问题讨论】:

    标签: c++ boost boost-hana


    【解决方案1】:

    Boost.Hana 的_s 使用的编译时字符串文字运算符是一个 gcc 扩展,必须通过定义 BOOST_HANA_CONFIG_ENABLE_STRING_UDL 来启用。

    您还必须将运算符从boost::hana::literals 导入到当前命名空间中。

    另外,有一个宏BOOST_HANA_STRING 可以使用,但它使用一个 lambda 并且在 C++14 中不能是 constexpr。

    虽然尚未最终确定,但 C++20 可能会将这个运算符以及字符串文字作为模板参数,这令人兴奋。 (here)

    这是一个完整的例子:

    #define BOOST_HANA_CONFIG_ENABLE_STRING_UDL
    #include <boost/hana.hpp>
    
    namespace hana = boost::hana;
    using namespace hana::literals;
    
    int main() {
      constexpr auto m1 = hana::make_map(
        hana::make_pair("key1"_s, hana::type_c<void>),
        hana::make_pair("key2"_s, hana::type_c<void>)
      );
    
      constexpr auto m3 = hana::make_map(
        hana::make_pair(hana::string<'k','e','y','1'>{}, hana::type_c<void>),
        hana::make_pair(hana::string<'k','e','y','2'>{}, hana::type_c<void>)
      );
    
      // not constexpr until C++17
      auto m2 = hana::make_map(
        hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<void>),
        hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<void>)
      );
    }
    

    【讨论】:

      【解决方案2】:

      无法编译的原因实际上是«_s»后缀。解决方法:用-DBOOST_HANA_CONFIG_ENABLE_STRING_UDL编译。

      或者使用hana::string_c&lt;'k', 'e', 'y', '1'&gt; 代替"key1"_shana::string_c&lt;'k', 'e', 'y', '2'&gt; 代替"key2"_s)

      说明

      这个后缀是 Hana 对名为“字符串文字运算符模板”的非标准 C++ 扩展的继承。它仅在 GCC 和 Clang 编译器上可用,因此 Hana 对它的支持默认禁用。

      这个扩展没有达到标准(经过多次尝试),因为它以最不有效的方式构造字符串类型 - 逐个字符。将它包含在标准中会鼓励它的使用,这会导致编译时间大大增加。

      没有其他选择,除了 boost::mpl::string 使用的技巧,它使用 4 字节 unicode 字符文字代替单字节字符文字,应该将编译时间缩短四次(但你仅限于ASCII 字符串)。

      【讨论】:

        猜你喜欢
        • 2021-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 1970-01-01
        相关资源
        最近更新 更多