Skip to main content
added 38 characters in body
Source Link
Enlico
  • 130
  • 8

I have a data which is a std::vector of a "small collection" of items of a given type struct Bunny {};.

I was vague about "small collection" because for now it's a collection of two of them, and so I'm just using the following alias

using Bunnies = std::array<Bunny,2>; // probably it'd be better to make it a struct, so that the compiler
                                     // could typecheck, but I think this is not relevant to my question

(Probably using a std::pair<Bunny,Bunny> would be ok too, but I think std::array<…,2> carries with it the idea that the entities must be homogeneous in type.)

That data, std::vector<Bunnies> is the input to a function:

auto fun(std::vector<Bunnies> editsinput) {

    // doThis stufffunction does no more than reorganizing the `Bunny`s
    // returnwhich somethingare in `input` in another, more complex way than just
    // "a `std::vector` of `std::array`s of 2 `Bunny`s".
    // So in my case `auto` is actually a `ResultOfBunnys` or really
    // `Result<Bunny>`.
};

At this point, however, I want to generalize fun, because I'm gonna pass to it not just Bunnys (in the form of a Bunnies), but also other stuff (in the form of some collection).

I guess templates is the way to go for such a generalization. So what could I do? I could do this:

template<typename ObjType>
auto fun(std::vector<std::array<ObjType,2>> editsinput) {

    // do stuff
    // return something
};

but it would hardcode std::array in the function interface. I could do this:

template<typename ObjsType>
auto fun(std::vector<ObjsType> editsinput) {
    using Obj = typename ObjsType::value_type;
    // do stuff
    // return something
};

but this would require that the ObjsType that I pass have a value_type member type. Or I could do this:

template<typename ObjType, typename ObjEditsType>ObjsType>
auto fun(std::vector<ObjEditsType>vector<ObjsType> editsinput) {

    // do stuff
    // return something
};

which forces the user to enter a template parameter which is consistent with the one which is deduced via the input argument.

I've been told that the first two options allow less flexibility than the third one. I kind of agree, but I would like to know a bit more about this topic. I don't even know whether there's a book about this things.

I have a data which is a std::vector of a "small collection" of items of a given type struct Bunny {};.

I was vague about "small collection" because for now it's a collection of two of them, and so I'm just using the following alias

using Bunnies = std::array<Bunny,2>; // probably it'd be better to make it a struct, so that the compiler
                                     // could typecheck, but I think this is not relevant to my question

(Probably using a std::pair<Bunny,Bunny> would be ok too, but I think std::array<…,2> carries with it the idea that the entities must be homogeneous in type.)

That data, std::vector<Bunnies> is the input to a function:

auto fun(std::vector<Bunnies> edits) {

    // do stuff
    // return something
};

At this point, however, I want to generalize fun, because I'm gonna pass to it not just Bunnys (in the form of a Bunnies), but also other stuff (in the form of some collection).

I guess templates is the way to go for such a generalization. So what could I do? I could do this:

template<typename ObjType>
auto fun(std::vector<std::array<ObjType,2>> edits) {

    // do stuff
    // return something
};

but it would hardcode std::array in the function interface. I could do this:

template<typename ObjsType>
auto fun(std::vector<ObjsType> edits) {
    using Obj = typename ObjsType::value_type;
    // do stuff
    // return something
};

but this would require that the ObjsType that I pass have a value_type member type. Or I could do this:

template<typename ObjType, typename ObjEditsType>
auto fun(std::vector<ObjEditsType> edits) {

    // do stuff
    // return something
};

which forces the user to enter a template parameter which is consistent with the one which is deduced via the input argument.

I've been told that the first two options allow less flexibility than the third one. I kind of agree, but I would like to know a bit more about this topic. I don't even know whether there's a book about this things.

I have a data which is a std::vector of a "small collection" of items of a given type struct Bunny {};.

I was vague about "small collection" because for now it's a collection of two of them, and so I'm just using the following alias

using Bunnies = std::array<Bunny,2>; // probably it'd be better to make it a struct, so that the compiler
                                     // could typecheck, but I think this is not relevant to my question

(Probably using a std::pair<Bunny,Bunny> would be ok too, but I think std::array<…,2> carries with it the idea that the entities must be homogeneous in type.)

That data, std::vector<Bunnies> is the input to a function:

auto fun(std::vector<Bunnies> input) {

    // This function does no more than reorganizing the `Bunny`s
    // which are in `input` in another, more complex way than just
    // "a `std::vector` of `std::array`s of 2 `Bunny`s".
    // So in my case `auto` is actually a `ResultOfBunnys` or really
    // `Result<Bunny>`.
};

At this point, however, I want to generalize fun, because I'm gonna pass to it not just Bunnys (in the form of a Bunnies), but also other stuff (in the form of some collection).

I guess templates is the way to go for such a generalization. So what could I do? I could do this:

template<typename ObjType>
auto fun(std::vector<std::array<ObjType,2>> input) {

    // do stuff
    // return something
};

but it would hardcode std::array in the function interface. I could do this:

template<typename ObjsType>
auto fun(std::vector<ObjsType> input) {
    using Obj = typename ObjsType::value_type;
    // do stuff
    // return something
};

but this would require that the ObjsType that I pass have a value_type member type. Or I could do this:

template<typename ObjType, typename ObjsType>
auto fun(std::vector<ObjsType> input) {

    // do stuff
    // return something
};

which forces the user to enter a template parameter which is consistent with the one which is deduced via the input argument.

I've been told that the first two options allow less flexibility than the third one. I kind of agree, but I would like to know a bit more about this topic. I don't even know whether there's a book about this things.

Source Link
Enlico
  • 130
  • 8

Templates for generic code and code flexibility

I have a data which is a std::vector of a "small collection" of items of a given type struct Bunny {};.

I was vague about "small collection" because for now it's a collection of two of them, and so I'm just using the following alias

using Bunnies = std::array<Bunny,2>; // probably it'd be better to make it a struct, so that the compiler
                                     // could typecheck, but I think this is not relevant to my question

(Probably using a std::pair<Bunny,Bunny> would be ok too, but I think std::array<…,2> carries with it the idea that the entities must be homogeneous in type.)

That data, std::vector<Bunnies> is the input to a function:

auto fun(std::vector<Bunnies> edits) {

    // do stuff
    // return something
};

At this point, however, I want to generalize fun, because I'm gonna pass to it not just Bunnys (in the form of a Bunnies), but also other stuff (in the form of some collection).

I guess templates is the way to go for such a generalization. So what could I do? I could do this:

template<typename ObjType>
auto fun(std::vector<std::array<ObjType,2>> edits) {

    // do stuff
    // return something
};

but it would hardcode std::array in the function interface. I could do this:

template<typename ObjsType>
auto fun(std::vector<ObjsType> edits) {
    using Obj = typename ObjsType::value_type;
    // do stuff
    // return something
};

but this would require that the ObjsType that I pass have a value_type member type. Or I could do this:

template<typename ObjType, typename ObjEditsType>
auto fun(std::vector<ObjEditsType> edits) {

    // do stuff
    // return something
};

which forces the user to enter a template parameter which is consistent with the one which is deduced via the input argument.

I've been told that the first two options allow less flexibility than the third one. I kind of agree, but I would like to know a bit more about this topic. I don't even know whether there's a book about this things.