Информация об изменениях

Сообщение Re[6]: Два одинаковых типа от 24.12.2024 12:39

Изменено 24.12.2024 13:43 rg45

Re[6]: Два одинаковых типа
Здравствуйте, ·, Вы писали:

·>Если использовать наследование, например как "struct Id : std::vector<int> {}", то сравниваться будут, а не должны.


Справедливое замечание. Но, опять же, масштаб трагедии здесь ровно такой же, как и при использовании целочисленных айдишников. А их использовали, используют и будут использовать.

Мне и самому вариант решения с наследованием не очень нравится. Я вообще не люблю наследование, стараюсь его избегать. Но даже в этом варианте решения возможно достичь приемлемой типовой безопасности, накидав в тело класса несколько дополнительных определений. А чтоб не делать это для каждого типа в отдельности, можно использовать шаблон:

http://coliru.stacked-crooked.com/a/2d464335e3ad11f3

#include <iostream>
#include <vector>

template <typename Category>
struct MultiDimensionalId : std::vector<int> 
{
    using vector::vector; // Открываем все конструкоры vector для использования в этом классе
    bool operator == (const MultiDimensionalId&) const = default;
    auto operator <=> (const MultiDimensionalId&) const = default;
    bool operator == (const auto&) const = delete;
    auto operator <=> (const auto&) const = delete;
};

using ElementId = MultiDimensionalId<class ElementCategory>;
using LogicalId = MultiDimensionalId<class LogicalCategory>;

int main()
{
    std::cout << (ElementId{} == ElementId{}) << std::endl;
    std::cout << (ElementId{} >= ElementId{}) << std::endl;
    std::cout << (ElementId{} < ElementId{}) << std::endl;
    //std::cout << (ElementId{} == LogicalId{}) << std::endl; // error: use of deleted function
    //std::cout << (ElementId{} >= LogicalId{}) << std::endl; // error: use of deleted function
}


Повторюсь, я не считаю это лучшим решением, и не говорю, что делать нужно только так.
Re[6]: Два одинаковых типа
Здравствуйте, ·, Вы писали:

·>Если использовать наследование, например как "struct Id : std::vector<int> {}", то сравниваться будут, а не должны.


Справедливое замечание. Но, опять же, масштаб трагедии здесь ровно такой же, как и при использовании целочисленных айдишников. А их использовали, используют и будут использовать.

Мне и самому вариант решения с наследованием не очень нравится. Я вообще не люблю наследование, стараюсь его избегать. Но даже в этом варианте решения возможно достичь приемлемой типовой безопасности, накидав в тело класса несколько дополнительных определений. А чтоб не делать это для каждого типа в отдельности, можно использовать шаблон:

http://coliru.stacked-crooked.com/a/2d464335e3ad11f3

#include <iostream>
#include <vector>

template <typename Category>
struct MultiDimensionalId : std::vector<int> 
{
    using vector::vector; // Открываем все конструкоры vector для использования в этом классе
    bool operator == (const MultiDimensionalId&) const = default;
    auto operator <=> (const MultiDimensionalId&) const = default;
    bool operator == (const auto&) const = delete;
    auto operator <=> (const auto&) const = delete;
};

using ElementId = MultiDimensionalId<class ElementCategory>;
using LogicalId = MultiDimensionalId<class LogicalCategory>;

int main()
{
    std::cout << (ElementId{} == ElementId{}) << std::endl;
    std::cout << (ElementId{} >= ElementId{}) << std::endl;
    std::cout << (ElementId{} < ElementId{}) << std::endl;
    //std::cout << (ElementId{} == LogicalId{}) << std::endl; // error: use of deleted function
    //std::cout << (ElementId{} >= LogicalId{}) << std::endl; // error: use of deleted function
}


Повторюсь, я не считаю это лучшим решением, и не говорю, что делать нужно только так. Как по мне, идиома строгих типов, в том или ином варианте исполнения, здесь была бы в самый раз.