Счетчик времени компиляции для отдельного идентификатора типа - PullRequest
0 голосов
/ 09 апреля 2020

Я пишу некоторый шаблон мета-программного кода. По некоторым причинам я хочу, чтобы каждый объект в моем коде имел различный тип. Исходный код выглядит следующим образом:

template<unsigned int index>
class Class1{

};

template<typename T1, typename T2, unsigned int index>
class Class2{
    std::tuple<T1*, T2*> v;
  public:
    Class2(T1* t1, T2* t2): v(std::tuple<T1*, T2*>(t1, t2)) {}
};

template<unsigned int index>
auto makeClass1() {
    return Class1<index>();
}

template<unsigned int index, typename T1, typename T2>
auto mul(T1& t1, T2& t2) {
    return Class2<T1, T2, index>(&t1, &t2);
}    

int main() {
    auto t1 = makeClass1<0>();  // Type of TT1 is Class1<0>
    auto t2 = makeClass1<1>();  // Type of TT2 is Class1<1>
    auto m1 = mul<0>(t1, t2);
    auto m2 = mul<1>(t1, t2); // Type of m2 is different from type of m1.
}

Этот код работает, но я sh мой код прост в использовании. Поэтому я хочу спросить, есть ли какое-нибудь решение, которое может сделать код таким:

template<unsigned int index>
class Class1{

};

template<typename T1, typename T2, unsigned int index>
class Class2{
    std::tuple<T1*, T2*> v;
  public:
    Class2(T1* t1, T2* t2): v(std::tuple<T1*, T2*>(t1, t2)) {}
};

template<unsigned int index = IncreaseCounter<?>::value>
auto makeClass1() {
    return Class1<index>();
}

template<unsigned int index = IncreaseCounter<?>::value, typename T1, typename T2>
auto operator*(T1& t1, T2& t2) {
    return Class2<T1, T2, index>(&t1, &t2);
}

int main() {
    auto t1 = makeClass1();  // Type of TT1 is Class1<0>
    auto t2 = makeClass1();  // Type of TT2 is Class1<1>
    auto m1 = t1*t2
    auto m2 = t1*t2; // Type of m2 is different from type of m1.
}

Примечание: я думаю, мне нужен счетчик времени компиляции. Но кроме решения для макросов: __COUNTER__ и __LINE__, я не могу найти другое решение во время компиляции. Макро-решение неэффективно для моего кода.

За исключением счетчика времени компиляции, любое другое решение в порядке.

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

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

В C ++ 20 вы можете сделать:

template <typename = decltype([]{})>
class Class1{};

template<typename T1, typename T2, typename = decltype([]{})>
class Class2{
    std::tuple<T1*, T2*> v;
  public:
    Class2(T1* t1, T2* t2): v(std::tuple<T1*, T2*>(t1, t2)) {}
};

template <typename T = decltype([]{})>
auto makeClass1() { return Class1<T>();}

template<typename T1, typename T2, typename T = decltype([]{})>
auto operator*(T1& t1, T2& t2) {
    return Class2<T1, T2, T>(&t1, &t2);
}

int main() {
    auto t1 = makeClass1();
    auto t2 = makeClass1(); // Type of t2 is different from type of t1.
    auto m1 = t1*t2;
    auto m2 = t1*t2; // Type of m2 is different from type of m1.

    static_assert(!std::is_same_v<decltype(t1), decltype(t2)>);
    static_assert(!std::is_same_v<decltype(m1), decltype(m2)>);
}

Демо .

0 голосов
/ 09 апреля 2020

Давайте рассмотрим суть вашего вопроса:

    auto m1 = t1*t2;
    auto m2 = t1*t2; // Type of m2 is different from type of m1.

У вас точно такое же выражение (t1*t2), но вы получите sh это выражение для создания двух разных типов!

В целом, ваша идея подсчета объектов во время компиляции потеряна. Что вы ожидаете в этом случае?

    for (int i = 0; i < 10; ++i) {
        auto m = t1*t2;
    }

Возвращаясь к своему коду: вам нужно как-то ввести этот индекс времени компиляции, как вы делаете в mul<index>: либо в mul, либо в тип результата (явный тип вместо auto + соответствующее преобразование).

...