Заставить пользовательский тип вести себя как std::stringC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Гость
 Заставить пользовательский тип вести себя как std::string

Сообщение Гость »


Мне нужно определить несколько структур, содержащих член типа std::string. Мне нужно заставить их вести себя как std::string. Другими словами, они должны быть легко конвертируемы в std::string, но не друг в друга. Экземпляры этих структур, в свою очередь, будут членами другого класса:

Код: Выделить всё

class Foo
{
Name_t m_name;
Description_t m_description;
// ...
};
Таким образом, функция, принимающая параметр типа Name_t, не должна вызываться с помощью экземпляра Description_t, даже если они оба являются std::string под капотом.
Как этого добиться правильно? Я попробовал перегрузить оператор std::string& для всех этих типов. Хотя, похоже, это работает. И я не уверен, следует ли объявлять их с помощью явного ключевого слова.
Пример:

Код: Выделить всё

#include 
#include 
#include 
#include 

struct Description_t
{
std::string value;

operator std::string&( ) noexcept
{
return value;
}

operator const std::string&( ) const noexcept
{
return value;
}
};

bool operator==( const Description_t& lhs, const Description_t& rhs ) noexcept
{
// This using declaration looks too verbose to my eyes!
using underlying_type = std::add_lvalue_reference_t<
std::add_const_t<
decltype( std::declval( ).value )> >;

return static_cast( lhs ) == static_cast( rhs );
// return lhs.value == rhs.value; // equivalent to the above statement
}

struct Name_t
{
std::string value;

operator std::string&( ) noexcept
{
return value;
}

operator const std::string&( ) const noexcept
{
return value;
}
};

bool operator==( const Name_t& lhs, const Name_t& rhs ) noexcept
{
// Again, this using declaration looks too verbose to my eyes!
using underlying_type = std::add_lvalue_reference_t<
std::add_const_t<
decltype( std::declval( ).value )> >;

return static_cast( lhs ) == static_cast( rhs );
// return lhs.value == rhs.value; // equivalent to the above statement
}

int main()
{
Description_t stock1 { "Hi!" };
Description_t stock2 { "Hi!" };
Name_t name1 { "Hello!" };
Name_t name2 { "Hello!" };

assert( name1 == name2 );
// assert( name1 == stock1 );
}
However, in the definition for underlying_type I had to do a static_cast to const std::string& by adding ref and const to it. Otherwise, the compiler would generate two inefficient copy constructions inside the operator== to compare the values of the two Name_t arguments. Is there a more concise way of doing this (other than lhs.value == rhs.value)?
Also should the operator== be a member function in the above cases?


Источник: https://stackoverflow.com/questions/781 ... -stdstring
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»