简体   繁体   English

为什么std :: is_literal_type <std::String> ==错误,我该如何解决?

[英]Why does std::is_literal_type<std::String> == false and how can I get around it?

I'm currently trying to use constexpr to define some input identification stuff: 我目前正在尝试使用constexpr定义一些输入标识的东西:

struct RangeParams {
    string legacyId;
    string fullname;
    string shortname;
    float min = -1; 
    float baseline = 0;
    float max = 1;
    float defaultValue = 0;
};

...

inline constexpr RangeParams curve1 = { "some_id", "my_name", ...};

Unfortunately, I get an error for the constexpr line saying 不幸的是,我对constexpr行说了一个错误

Constexpr variable cannot have non-literal type 'const RangeParams' Constexpr变量不能具有非文字类型“ const RangeParams”

So, I dug into it to figure out what part of this is non-literal, and string was the culprit. 因此,我仔细研究了其中的哪些部分是非文字的,而string是罪魁祸首。

std::cout << std::is_literal_type<float>::value;  // output: 1
std::cout << std::is_literal_type<string>::value;  // output: 0

Finding this has highlighted an important fact for me which is that my understanding of literal-types is rather flawed. 找到这一点对我来说是一个重要的事实,那就是我对文字类型的理解相当有缺陷。 For the most part, I'd simply thought of them as being the basics (numbers, strings, booleans, structs made of those things). 在大多数情况下,我只是将它们视为基本知识(数字,字符串,布尔值,由这些东西组成的结构)。

So why would a simple string not be a literal type? 那么,为什么简单的字符串不是文字类型呢? What's the gotcha here? 这是什么陷阱?

Also, how can I get around this? 另外,我该如何解决? I'm trying to make a global out of my RangeParams and the most modern answer to this question ( Defining global constant in C++ ) appears not be working. 我试图从我的RangeParams中创建一个全局变量,并且这个问题的最现代答案( 在C ++中定义全局常量 )似乎无法正常工作。

std::string is not a literal. std::string不是文字。 const char[] is. const char[]是。 The gotcha is that a std::string is a container of a dynamic size. 问题是std::string是动态大小的容器。 No, you can't get around this and still use std::string . 不,您无法绕开它,仍然使用std::string std::string is unusable in constexpr context. std::string在constexpr上下文中不可用。

You might want to replace std::string with const char* in your code: 您可能需要在代码中用const char*替换std::string

struct RangeParams {
    const char* legacyId;
    const char* fullname;
    const char* shortname;
    float min = -1; 
    float baseline = 0;
    float max = 1;
    float defaultValue = 0;
};

It's not exactly the same, but given the lack of context, it's hard to justify what did you exactly need the std::string for, thus it's uncertain that a const char* will be a suitable alternative. 它并不完全相同,但是由于缺乏上下文,很难证明您确实需要std::string的原因,因此不确定const char*将是合适的选择。

EDIT: A short example should help to understand the misconception. 编辑:一个简短的例子应该有助于理解误解。 What is the type of 0 ?. 0是什么类型? It's an int . 这是一个int What's the type of 'a' ? 什么是'a'类型? It's a char . 这是一个char What's the type of "abc" ? 什么是"abc"类型? It's not std::string , it's const char[4] ! 不是std::string ,而是const char[4]

我可以初始化一个 std::array <uint8_t with a string literal?< div><div id="text_translate"><p> 我写了很多 C 代码,使用 UART 串口与仪器交互。 我正在开始一个新项目,我试图在 C++ 中使用更面向 object 的方法。 这是我过去使用 C 定义和发送命令的方式。</p><pre> uint8_t pubx04Cmd[] = "$PUBX,04*37\r\n"; HAL_UART_Transmit(&amp;hUART1, pubx04Cmd, sizeof(pubx04Cmd), 5000);</pre><p> 这非常简单。 C++ std::array具有内置的大小,看起来很有用。 但这是我想出如何做到这一点的唯一方法。</p><pre> const char pubx04CString[] = "$PUBX,04*37\r\n"; std::array&lt;uint8_t, 14&gt; pubx04CPPArray; std::copy(std::begin(pubx04CString), std::end(pubx04CString), pubx04CPPArray.begin()); HAL_UART_Transmit(&amp;hUART1, pubx04CPPArray.data(), pubx04CPPArray.size(), 5000);</pre><p> 与 C 方法相比,这似乎相当笨拙。</p><ul><li><p> 使用std::array是否有更清洁的方法?</p></li><li><p> 在这种情况下使用std::array与 C arrays 有什么真正的好处吗?</p></li></ul></div></uint8_t> - Can I initialize a std::array<uint8_t with a string literal?

暂无
暂无

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

相关问题 libc ++的std :: is_literal_type如何工作? - How does libc++'s std::is_literal_type work? C ++ 17中不推荐使用std :: is_literal_type - Deprecated std::is_literal_type in C++17 如何转换 C++17 的“if constexpr(std::is_literal_type<t> ::value)" 到 C++11 SFINAE 代码?</t> - How to convert C++17's "if constexpr(std::is_literal_type<T>::value)" to C++11 SFINAE code? std::string 是文字类型吗? - Is std::string a literal type? 如何从枚举类型获取std :: string? - How can I get a std::string from an enum type? 为什么 std::vector 的字符串文字初始化列表不能创建 std::vector<std::string> 在 C++ 中?</std::string> - Why can't a string literal initializer list for a std::vector create a std::vector<std::string> in C++? 我可以初始化一个 std::array <uint8_t with a string literal?< div><div id="text_translate"><p> 我写了很多 C 代码,使用 UART 串口与仪器交互。 我正在开始一个新项目,我试图在 C++ 中使用更面向 object 的方法。 这是我过去使用 C 定义和发送命令的方式。</p><pre> uint8_t pubx04Cmd[] = "$PUBX,04*37\r\n"; HAL_UART_Transmit(&amp;hUART1, pubx04Cmd, sizeof(pubx04Cmd), 5000);</pre><p> 这非常简单。 C++ std::array具有内置的大小,看起来很有用。 但这是我想出如何做到这一点的唯一方法。</p><pre> const char pubx04CString[] = "$PUBX,04*37\r\n"; std::array&lt;uint8_t, 14&gt; pubx04CPPArray; std::copy(std::begin(pubx04CString), std::end(pubx04CString), pubx04CPPArray.begin()); HAL_UART_Transmit(&amp;hUART1, pubx04CPPArray.data(), pubx04CPPArray.size(), 5000);</pre><p> 与 C 方法相比,这似乎相当笨拙。</p><ul><li><p> 使用std::array是否有更清洁的方法?</p></li><li><p> 在这种情况下使用std::array与 C arrays 有什么真正的好处吗?</p></li></ul></div></uint8_t> - Can I initialize a std::array<uint8_t with a string literal? 为什么我不能得到std :: function <std::vector<T> :: iterator&gt;绑定到返回该类型的lambda? - Why can't I get std::function<std::vector<T>::iterator> to bind to lambda returning that type? 我如何将这个 std::string 转换为 std::basic 字符串? - How would I get convert this std::string into a std::basic string? 我如何将std :: string复制到带有std :: string字段的结构中 - How can I std::copy a string to a struct with the std::string fields
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM