псевдоним общего типа, которые несовместимы друг с другом - PullRequest
0 голосов
/ 06 июня 2018

Я пытаюсь создать своего рода «псевдоним универсального типа», то есть, например, я хочу определить тип как int, но с аргументом универсального типа, который затем делает его несовместимым с экземплярами других типов.

Я пытался сделать это с помощью шаблонов псевдонимов:

template <typename T>
using NumberWithSemantics = int;

Но проблема в том, что все экземпляры, независимо от типа T, считаются равными, например:

struct A {};
struct B {};

NumberWithSemantics<A> getThing() {
    return 14;
}

int processDifferentThing(NumberWithSemantics<B> b) {
    return b * 3;
}

int main() {
    auto a = getThing();
    return processDifferentThing(a); // unfortunately compiles just fine
}

Есть ли способ определить какой-то псевдоним универсального типа, который запрещает смешивать различные экземпляры шаблона?

1 Ответ

0 голосов
/ 08 июня 2018

C ++ имеет псевдоним типа, но это только слабый псевдоним типа.Когда вы говорите

typedef int MyType;

или

using MyType = int;

, вы говорите компилятору: «всякий раз, когда вы видите MyType, представьте, что вы только что видели int вместо этого».Тогда нет никакой разницы между MyType i и int i;оба создают переменную с именем i типа int.Создание объявления using для шаблона не помогает;все типы эквивалентно означают int.

. То, что вы хотите сделать, - это создать фактический новый тип.Для этого вам нужно объявить это с struct или class, а не просто using.Даже если они выглядят одинаково, система thpe будет обрабатывать каждый новый тип, созданный таким образом, как отдельный тип;по расширению, если вы создадите шаблон struct, каждый экземпляр будет иметь новый тип.

Следовательно, минимальное потенциальное решение будет:

template <typename T>
struct NumberWithSemantics { int i; };

Тогда вы можете использовать NumberWithSemantics<A> и NumberWithSemantics<B> как разные типы.Однако вам нужно будет повторять .i, чтобы получить действительное значение, что может затруднить чтение вашего кода.Существуют различные возможные способы обойти это, для чего я рекомендую прочитать эту часть серии Strong Types на Fluent C ++.

...