joboccara / NamedType

Implementation of strong types in C++
MIT License
773 stars 85 forks source link

Why NamedType couldn't be default constructible? #14

Closed ksergey closed 4 years ago

ksergey commented 6 years ago

This is not working for me

using QueueName = NamedType< std::string, struct QueueNameTag >;
...
QueueName name;

Is there any reason why NamedType() not exists?

OvermindDL1 commented 6 years ago

Did you include the headers and so forth? What is your complete compileable example?

ksergey commented 6 years ago

@OvermindDL1 Of course I include headers

Just look at NamedType constructors (in flie named_type_impl.hpp):

    // constructor
    explicit constexpr NamedType(T const& value) : value_(value) {}
    template<typename T_ = T, typename = IsNotReference<T_>>
    explicit constexpr NamedType(T&& value) : value_(std::move(value)) {}

    // get
    constexpr T& get() { return value_; }
    constexpr T const& get() const {return value_; }

There is no constructor constexpr NamedType() {}

And question is why no default constructor exists?

Actually I want to do something like that:

using QueueName = NamedType< std::string, struct QueueNameTag >;
using Endpoint = std::tuple< Consumer, QueueName >;

std::vector< Endpoint > storage;

auto& entry = storage.emplace_back();
std::get< QueueName >(entry) = QueueName{"bla-bla-bla"};
std::get< Consumer >(entry) = Consumer{"bla-bla-bla", param1, param2};

Without NamedType default constructor it not impossible

OvermindDL1 commented 6 years ago

Oh default constructable! Hmm, good question, I've not needed that yet...

FlorianWolters commented 6 years ago

I also think that default constructing of strong types would be nice, since it is a core language feature as well and well-known Standard Library types (e.g. std::string) also provide default constructors.

viboes commented 6 years ago

Yes, there is a missing default generate default construtor

    constexpr NamedType() = default;

Note that the default constructor should do better by default than the underlying type, that is, it shouldn't do zero-initialization. If we want to make it possible to have strong types that support uninitialized data member, the library should add it.

Maybe, you could workaround this by inheriting your string type from NamedTypeand creating explicitly your own default constructor

class X : public  NamedType<int, X> {
public:
  X(): NamedType<int,X>(int{}) {};
  using NamedType::NamedType;

};

or even generalize it in a class ZST (Zero initialized Strong Type)

template <class UT, class Tag> 
class ZST : public NamedType<UT, ST> {
public:
  ST(): NamedType<UT,ST>(UT{}) {};
  using NamedType::NamedType;

};

using X = ZST<int, struct X_tag>;

Not tested of course.

thongpv87 commented 5 years ago

I also need this.

Shachlan commented 5 years ago

Opened a PR for this: https://github.com/joboccara/NamedType/pull/31

joboccara commented 4 years ago

PR accepted, thanks!

knatten commented 4 years ago

I guess this issue can be closed now, then?