3

I hope to inherit all the methods including constructors of std::array. I try

template<class T, size_t N>
class Vec : public array<T, N>
{
public:
    using array<T, N>::array;

    Vec operator+(Vec const& rhs) const
    {
        Vec res;
        transform(begin(), end(), rhs.begin(), res.begin(), plus);
        return res;
    }

};

But got some compilation errors.

  1. 'begin': no matching overloaded function found
  2. I cannot do Vec<int, 2> v{1, 2}; like std arrays even constructors are inherited.

I may misunderstand something. How to solve those errors. Any better ideas to add arithmetic operators on std::array. Thanks!

user1899020
  • 13,167
  • 21
  • 79
  • 154
  • 6
    [Ahem](https://en.cppreference.com/w/cpp/numeric/valarray) – Lightness Races in Orbit May 12 '19 at 00:44
  • First you have a typo (res should be rhs), Second std::plus is a type, transform expects *an instance of that type*, third you needs to use this-> in front of begin & end (something about two phase lookup i think?). Fourth, what Lightness said. Remove the using array::array to fix brace init (I have no clue why but I think it has to do with array not having a user defined ctor?) ... [I think it works now?](http://coliru.stacked-crooked.com/a/fbbf0a804c5e768e) – Borgleader May 12 '19 at 00:47
  • Sure would be great if this was a [mcve] so anyone wanting to copy/paste it didn't need to supply all the rest. – Retired Ninja May 12 '19 at 00:58
  • Be careful of https://stackoverflow.com/questions/2034916/is-it-okay-to-inherit-implementation-from-stl-containers-rather-than-delegate I don't think it applies yet, but I always do has-a container rather than is-a container, just in case someone tries to extend the class. – Kenny Ostrom May 12 '19 at 14:18

2 Answers2

2

Ok, hold on, the reason is complicated, but fear not, the solution is simple. Read on.

array is a template so the members of the class array<T, N> aren't known before the template instantiation (remember a template can be specialized). And because begin appears to be non-dependent on any template parameters its name is resolved at the first phase lookup, before the instantiation of array<T, N>, i.e. before the members of array<T, N> are known. That's why you get begin not found or similar error.

The simple solution is to use this->begin. This way begin will be resolved at the second phase lookup (after std::array<T, N> is instantiated) because now it is clear that begin can be a member of the inherited template class.

Also, plus should be plus<>{} or plus{} in C++17.

And a recommendation: try to avoid using namespace std Why is "using namespace std" considered bad practice?

Two phase lookup - explanation needed

bolov
  • 72,283
  • 15
  • 145
  • 224
  • Thanks, I am still wondering why cannot use aggregate initialization `Vec v{1, 2};`. I am using VS2017. – user1899020 May 12 '19 at 01:07
  • I am using namespace std in my namespace. Not sure if it is okay or still bad practice. – user1899020 May 12 '19 at 01:09
  • @user1899020 because `Vec` is not an aggregate – bolov May 12 '19 at 01:34
  • https://stackoverflow.com/questions/24280521/stdarray-constructor-inheritance On the topic of using namespace std, templates still have to be in a header, right? Therefore this isn't restricted to your compilation unit. You're forcing everyone who uses this to put all of std in their namespace. Or you could write "std::" a few times, which seems a reasonable burden. – Kenny Ostrom May 12 '19 at 14:16
1

If you need only add arithmetic operations for std::array, I don't think that you need to create a class for this purpose. You can just define nonmember template operators that will work without direct access to std::array implementation.

template <typename T, size_t N>
auto operator+(const array<T, N>& ob1, const array<T, N>& ob2)->array<T, N> {
    array<T, N> res;
    for (int i = 0; i < N; ++i)
        res[i] = ob1[i] + ob2[i];
    return res; 
}

And so on for other arithmetic operations.

  • or simply use [`std::valarray`](https://en.cppreference.com/w/cpp/numeric/valarray), no need to create a new class – phuclv May 12 '19 at 02:31