首页 > 解决方案 > 不同类型标识符的编译时计数器

问题描述

我正在编写一些模板元编程代码。出于某些原因,我想让代码中的每个对象都具有不同的类型。原始代码如下所示:

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.
}

此代码有效,但我希望我的代码易于使用。所以我想问有没有任何解决方案可以使代码看起来像这样:

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__,我找不到任何其他编译时解决方案。宏解决方案对我的代码无效。

除了编译时计数器,任何其他解决方案都可以。

感谢您阅读我的问题。由于我的英语表达能力较差,请多多包涵。

标签: c++templatestemplate-meta-programming

解决方案


在 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)>);
}

演示


推荐阅读