Extending class functionality with post-declaration methods

I very often encounter the problem that I want to implement a data structure, and would like to allow users to expand its functionality; this is to add functionality, but not bytes to the data structure. An example would be the extension std :: vector with the sum method:

#include <iostream>

#include <vector>

// for the header file
template<>
int std::vector<int>::sum();

//for the object file
template<>
int std::vector<int>::sum() {
    int s=0;
    for(auto v = this->begin(); v!=this->end(); ++v) s+=*v;
    return s;
}


int main() {
    std::vector<int> numbers;
    numbers.push_back(5);
    numbers.push_back(2);
    numbers.push_back(6);
    numbers.push_back(9);

    std::cout << numbers.sum() << std::endl;

    return 0;
}

See: http://ideone.com/YyWs5r

So this is illegal, since you cannot add functions to a class like this. Obviously, this is some kind of design decision C ++ (11). It can be circumvented in two ways: definition

int sum(std::vector<int> &v) { ... }

std:: sort, , ++ (11). , , , ++. std::vector. , , , () . , , , , . , , std:: sort w.r.t. .

std::vector, , :

  • , , . , , () ​​ . , - , .
  • , , sum_vector mean_vector .

" ++", , ( ++ ). , , . ? , ; ?

: , , , , , , .

+4
2

, .

, std::vector, .

. sum , , begin() end() std::vector

#include <algorithm>
#include <iterator>
#include <vector>

template<class Container, class Ret = decltype(*begin(c))>
Ret sum(Container const& c)
{
    return std::accumulate(begin(c), end(c), Ret{});
}
+2

:

#include <iostream>

class Foo{
    int a;
public:
    Foo(int a){this->a = a;}
    int getA(){return this->a;}
    void * extendedMethod(void *(*func)(int, char **, Foo*), int argc, char **argv){
        return func(argc, argv, this);
    }

};

void * extendFooWith(int argc, char **argv, Foo* self){
    /* You can call methods on self... but still no access to private fields */
    std::cout << self->getA();
    return self;
}

int main(int argc, char const *argv[])
{
    Foo foo(5);
    foo.extendedMethod(extendFooWith, 0 /*argc*/, NULL /*argv*/);
    return 0;
}

. extendedMethod(), - : return func(this->a, argv, this);, . extendedMethod(), , , , func(), extendedMethod() .

0

Source: https://habr.com/ru/post/1543744/


All Articles