4 ms·
I find that there's no use case for a constexpr std::string. Maybe I'm just not imaginative enough. If I want a string literal constant, I use string_view which
by kccqzy 3y ago
I find that there's no use case for a constexpr std::string. Maybe I'm just not imaginative enough. If I want a string literal constant, I use string_view which can be constexpr. If somehow I need an actual std::string object, I use a regular const not constexpr. What would be a use case that prompts the author to explore using constexpr with std::string?
- hudsonwillis 3y agoIt enables users to process string at compile time. You can implement a constexpr getRFC3339DateString(int year, int month, int day) -> string and then construct a constexpr string list.
- kccqzy 3y agoBut what can you do with that string list afterwards? You can't store it anywhere to be accessed at run time, can you?
- Chabsff 3y agoThe important part is that all the intermediate strings used during the computation are constexpr, to guarantee that the work happens during compilation. Also, constexpr symbols can be demoted to regular const as needed by the compiler if necessary, such as when getting a pointer to one. constexpr doesn't mean "compile-time only", it means "compile-time compatible"
- lldb 3y agoRight - you can use the std::string at compile time but since it allocates dynamically you need to copy to a fixed size char[]/std::array to use at runtime.
- maccard 3y ago> If I want a string literal constant, I use string_view which can be constexp That assumes your API accepts string views. How do you pass a string_view (safely) to fopen, or CreateFile (on windows)?
- eesmith 3y agoWhile (I think) I understand your broader point, when would you pass a string created by a constexp to fopen() or CreateFile?
- cshokie 3y agoHard-coding a relative file path seems like an obvious example. For example a config file with settings. The file will always have the same name so heap allocations and mutability are not needed.
- eesmith 3y agoMy config file paths have either been constant (".dotfile") or required run-time information that could not be constexpr'ed. I don't see how constexpr would be useful. Then again, I am primarily a Python and C programmer, so there is likely some underlying reasoning I'm missing.
- cshokie 3y agoconst std::string foo = “.dot file”; in C++ cannot change after construction, but is not compile time constant. This means that it has to run some code and allocate some memory at runtime. In contrast constexpr is fully compile time and ends up in the read only portion of the binary. No code code execution or allocations necessary.
- maccard 3y agoThey were examples, they're widely used C apis. Anything that passes through to glibc, windows or posix will have this problem.
- eesmith 3y agoI lack the intuition to understand why is it useful to constexpr path names. Could you elaborate?
- o11c 3y agoIf it was real constexpr it would be useful, e.g. concatenation is commonly desired and requires awkward workarounds currently.
- hot_gril 3y agoI use constexpr char[] for string literal constants just because it's a little more compatible. Some things can't take string_view.
- criddell 3y agoWhy not use a std::array? Otherwise won't you a second variable for the string length?
- hot_gril 3y ago`constexpr char kFoo[] = "bar"`, then kFoo can be used like an std::string and passed into things that take const std::string& or string_view. The length is part of that. Or is that actually doing a copy?
- vitus 3y agoFor both const std::string& and std::string_view, you're (potentially) incurring a runtime invocation of strlen. For const std::string&, you're further incurring a copy in order to create a temporary std::string.
- hot_gril 3y agoWhoops. As you can maybe tell, the stuff I use C++ for isn't so much about performance.
- criddell 3y agoI think you still need the length though unless you can guarantee the string will never have any nulls in it. In Windows, there are API calls that take strings with embedded nulls (and that are typically terminated with a two nulls in a row). So you might need to deal with a string that looks like "foo\0bar\0\0".
- mike_hock 3y agoWould definitely be more useful if you could actually materialize the eventual result into something that's visible at runtime. If there was reflection, it would be useful to talk about class names, function names, etc, at compile time.
- scatters 3y agoYou can use `std::array<char>` (which, as it happens, is a literal type) as an intermediary when performing materialization. A nice toy example is to build a comma-separated string listing enumerators: template<class E> requires std::is_enum_v<E> constexpr std::string_view joinedEnum() { constexpr auto generate = [] -> std::string { return []<template<class...> class L, class... D>(L<D...>) { std::string str; (((str += (str.empty() ? "" : ", ")) += D::name), ...); return str; }(boost::describe::describe_enumerators<E>()); }; static constexpr auto arr = [&] { constexpr std::size_t N = generate().size(); std::array<char, N> arr; std::char_traits<char>::copy(arr.data(), generate().data(), N); return arr; }(); return std::string_view(arr); } Note that you have to generate the constexpr std::string twice; once for its size, once for its contents. But you assume that the compiler can memoize the result.
- rewmie 3y ago> I find that there's no use case for a constexpr std::string. Maybe I'm just not imaginative enough. Putting together strings through string interpolation involving somewhat expensive operations is a common usecase. Given the choice, it's preferable to not have to compute them each and every single time a function is invoked.
- dtho 3y agoThe constructor of std::string is constexpr in C++20. A runtime call to 'strlen' (or equivalent) can be optimized out by computing the string's length at compile time and initializing the object accordingly.
- rewmie 3y ago> The constructor of std::string is constexpr in C++20. If I recall correctly, from C++20 onward all member functions of std::string are constexpr.
- fooker 3y agoGenerate a large number of strings and maps programmatically in compile time. You are pretty much limited to macros and macro-like languages (llvm-tablegen) if you want to do this today.
- mostlylurks 3y agoYou can also do the same with templates quite easily, but the resulting compile times are going to be absolutely atrocious.
- fooker 3y agoA bunch of constexpr stuff since C++14 onwards have been added just to make meta-programming more usable. Users, library writers, and compiler writers all benefit from this in some way.
- deleted 3y ago[deleted]
- ghotli 3y agoMaybe I'm just not imaginative enough but what sort of use-case is this sort of thing for?
- fooker 3y agoParsers, and any text heavy application really.