c++ - How to use the template array type of a template class in a template function? - Stack Overflow

I'm trying to use the array type that I declared within a class that specifies the size. In practi

I'm trying to use the array type that I declared within a class that specifies the size. In practice, the class will have several declarations based off the array size, and is only there to help logically group everything together. It could be a namespace if we were allowed to make those templates, and it works in a vacuum.

However, when the user also wants to call this class from a template function, things get messy and I'm wondering how to get everything to play nicely together.


Ideally, I do not want the user directly calling/controlling SubArray's size, as it won't also be exactly "N". And several types will also be built out with N, and used throughout user space. However, type T (int in the example) can be varied throughout and the user can control a lot more freely. Additionally, there will more than just SubArray<T>, ex: SubArray2<T>, SubMatrix<T>, SubTree<T>, etc.

#include <array>

// Originally, the code was tested around something like `Foo`,
// but was translated to `Bar` for more flexibility. 

class Foo {
public:
    static int constexpr CONST_SIZE = 4;
    template <class T>
    using SubArray = std::array<T, CONST_SIZE>;
};

template <int N>
class Bar {
public:
    template <class T>
    using SubArray = std::array<T, N>;
};


void GoodFunc1() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<4>;
    MyBar::SubArray<int> bar_sub{};
}

template <int N>
void GoodFunc2() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<4>;
    MyBar::SubArray<int> bar_sub{};
}

template <int N>
void ErrorFunc() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<N>;
    // MyBar::SubArray<int> bar_sub{};
    // error: expected primary-expression before ‘int’
    // |     MyBar::SubArray<int> bar_sub{};
    // |                     ^~~
}

// This works, but I don't want to make the user initialize every variable like that...
template <int N>
void UglyFunc() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<N>;
    typename MyBar::template SubArray<int> bar_sub;
}

I'm trying to use the array type that I declared within a class that specifies the size. In practice, the class will have several declarations based off the array size, and is only there to help logically group everything together. It could be a namespace if we were allowed to make those templates, and it works in a vacuum.

However, when the user also wants to call this class from a template function, things get messy and I'm wondering how to get everything to play nicely together.


Ideally, I do not want the user directly calling/controlling SubArray's size, as it won't also be exactly "N". And several types will also be built out with N, and used throughout user space. However, type T (int in the example) can be varied throughout and the user can control a lot more freely. Additionally, there will more than just SubArray<T>, ex: SubArray2<T>, SubMatrix<T>, SubTree<T>, etc.

#include <array>

// Originally, the code was tested around something like `Foo`,
// but was translated to `Bar` for more flexibility. 

class Foo {
public:
    static int constexpr CONST_SIZE = 4;
    template <class T>
    using SubArray = std::array<T, CONST_SIZE>;
};

template <int N>
class Bar {
public:
    template <class T>
    using SubArray = std::array<T, N>;
};


void GoodFunc1() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<4>;
    MyBar::SubArray<int> bar_sub{};
}

template <int N>
void GoodFunc2() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<4>;
    MyBar::SubArray<int> bar_sub{};
}

template <int N>
void ErrorFunc() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<N>;
    // MyBar::SubArray<int> bar_sub{};
    // error: expected primary-expression before ‘int’
    // |     MyBar::SubArray<int> bar_sub{};
    // |                     ^~~
}

// This works, but I don't want to make the user initialize every variable like that...
template <int N>
void UglyFunc() {
    Foo::SubArray<int> foo_sub{};
    using MyBar = Bar<N>;
    typename MyBar::template SubArray<int> bar_sub;
}

Share Improve this question edited Mar 25 at 16:31 Spencer Smith asked Mar 25 at 15:54 Spencer SmithSpencer Smith 133 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

You could possibly add a helper template:

template<class T, class U>
using SubArray = T::template SubArray<U>;

template <int N>
void NotErrorFuncAnymore() {
    SubArray<Foo, int> foo_sub{};
    // or the original:
    //Foo::SubArray<int> foo_sub{};

    using MyBar = Bar<N>;
    SubArray<MyBar, int> bar_sub{};
    // or:
    //SubArray<Bar<N>, int> bar_sub{}; 
}

You can use a templated type alias, like so:

#include <array>

class Foo {
public:
    static int constexpr CONST_SIZE = 4;
    template <class T>
    using SubArray = std::array<T, CONST_SIZE>;
};

template <int N>
class Bar {
public:
    template <class T>
    using SubArray = std::array<T, N>;
};

template <class T, int N>
using SubArrayAlias = typename Bar<N>::template SubArray<T>;

template <int N>
void CleanFunc() {
    Foo::SubArray<int> foo_sub{};
    SubArrayAlias<int, N> bar_sub{};
}

int main() {
    CleanFunc<4>();
    CleanFunc<8>();

    return 0;
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744184764a4562154.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信