Сообщение 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
Повторюсь, я не считаю это лучшим решением, и не говорю, что делать нужно только так.
·>Если использовать наследование, например как "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
Повторюсь, я не считаю это лучшим решением, и не говорю, что делать нужно только так. Как по мне, идиома строгих типов, в том или ином варианте исполнения, здесь была бы в самый раз.
·>Если использовать наследование, например как "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
}
Повторюсь, я не считаю это лучшим решением, и не говорю, что делать нужно только так. Как по мне, идиома строгих типов, в том или ином варианте исполнения, здесь была бы в самый раз.