For some types, the standard explicitly states that they are trivially copyable. For example, std::chrono::day
is such a type.
But, for std::string_view
, there is no such statement. Yet, it seems that it fulfills the requirements of being trivially copyable (or maybe I overlooked something?).
The question is, can I count on that std::string_view
is trivially copyable?
A trivially copyable class is a class that: has no non-trivial copy constructors, has no non-trivial move constructors, has no non-trivial copy assignment operators, has no non-trivial move assignment operators, and has a trivial destructor.
std::array however, has a static size set at compile time. It does not have internal pointers and can therefore be copied simply by using memcpy . It therefore is trivial to copy.
So, frequently, you can pass string_view by reference and get away with it. But you should pass string_view by value, so that the compiler doesn't have to do those heroics on your behalf. And so that your code-reviewer doesn't have to burn brain cells pondering your unidiomatic decision to pass by reference.
In the libstdc++ implementation for instance, optional<T> is not trivially copyable for any T . The only explicit discussion of triviality is that if T is trivially destructible, then optional<T> shall also be trivially destructible.
I believe it's strongly implied.
[string.view.template] declares the class template as (I'm omitting everything that isn't strictly relevant to this question):
template<class charT, class traits = char_traits<charT>>
class basic_string_view {
public:
// types
using const_pointer = const value_type*;
using size_type = size_t;
private:
const_pointer data_; // exposition only
size_type size_; // exposition only
};
And [objects.within.classes] says:
For the sake of exposition, some subclauses provide representative declarations, and semantic requirements, for private members of classes that meet the external specifications of the classes. The declarations for such members are followed by a comment that ends with exposition only, as in:
streambuf* sb; // exposition only
An implementation may use any technique that provides equivalent observable behavior.
Whether or not std::string_view
exactly contains two members of types char const*
and size_t
or not is unspecified - but the class must have equivalent observable behavior to how such an implementation would behave. And such an implementation would be trivially copyable.
Also, many member functions are declared constexpr
, which itself in C++17 required trivial destruction (otherwise, this annotation would be ill-formed NDR).
There is now a proposal, P2251, to go ahead and actually explicitly state that basic_string_view
(and span
) are trivially copyable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With