Как Производный класс может наследовать статическую функцию от Базового класса?

Цитата из документации о тяге :

Обобщение состоит в том, что если элемент появляется m раз в [keys_first1, keys_last1) и n раз в [keys_first2, keys_last2 ) (где m может быть нулем), то в диапазоне выходных данных клавиш появляется min (m, n) раз

blockquote>

. Поскольку comp содержит только один ключ один раз, n=1 и поэтому min(m,1) = 1.

Чтобы получить «все валы, где соответствующий ключ содержится в comp», вы можете использовать подход моего ответа на аналогичную проблему .

Аналогично, код примера выполняет следующие шаги:

  1. Получить наибольший элемент из d_comp. Это предполагает, что d_comp уже отсортирован.
  2. Создайте вектор d_map размера largest_element+1. Скопируйте 1 во все позиции записей d_comp в d_map.
  3. Скопируйте все записи из d_vals, для которых есть запись 1 в d_map на d_result ,
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    
    #define PRINTER(name) print(#name, (name))
    void print(const char* name, const thrust::device_vector& v)
    {
        std::cout << name << ":\t";
        thrust::copy(v.begin(), v.end(), std::ostream_iterator(std::cout, "\t"));
        std::cout << std::endl;
    }
    
    int main()
    {
        int keys[] = {1, 1, 1, 3, 4, 5, 5};
        int vals[] = {1, 2, 3, 4, 5, 6, 7};
        int comp[] = {1, 5};
    
        const int size_data = sizeof(keys)/sizeof(keys[0]);
        const int size_comp = sizeof(comp)/sizeof(comp[0]);
    
        // copy data to GPU
        thrust::device_vector d_keys (keys, keys+size_data);
        thrust::device_vector d_vals (vals, vals+size_data);
        thrust::device_vector d_comp (comp, comp+size_comp);
    
        PRINTER(d_keys);
        PRINTER(d_vals);
        PRINTER(d_comp);
    
        int largest_element = d_comp.back();
    
        thrust::device_vector d_map(largest_element+1);
    
        thrust::constant_iterator one(1);
        thrust::scatter(one, one+size_comp, d_comp.begin(), d_map.begin());
        PRINTER(d_map);
    
        thrust::device_vector d_result(size_data);
        using namespace thrust::placeholders;
        int final_size = thrust::copy_if(d_vals.begin(),
                                        d_vals.end(),
                                        thrust::make_permutation_iterator(d_map.begin(), d_keys.begin()),
                                        d_result.begin(),
                                        _1
                                        ) - d_result.begin();
        d_result.resize(final_size);
    
        PRINTER(d_result);
    
        return 0;
    }
    

выход:

d_keys:     1   1   1   3   4   5   5   
d_vals:     1   2   3   4   5   6   7   
d_comp:     1   5   
d_map:      0   1   0   0   0   1   
d_result:   1   2   3   6   7   

24
задан Arkadiy 5 February 2009 в 12:54
поделиться

2 ответа

Можно легко наследоваться тому классу:

class Derived: public TimerEvent {
    ...
};

Однако Вы не можете переопределить HandleTimer в своем подклассе и ожидать, что это будет работать:

TimerEvent *e = new Derived();
e->HandleTimer();

Это вызвано тем, что статические методы не имеют записи в vtable, и не могут таким образом быть виртуальными. Можно однако использовать "пустой* Аргумент" для передачи указателя на экземпляр... что-то как:

struct TimerEvent {
    virtual void handle(int fd, short event) = 0;

    static void HandleTimer(int fd, short event, void *arg) {
        ((TimerEvent *) arg)->handle(fd, event);
    }
};

class Derived: public TimerEvent {
    virtual void handle(int fd, short event) {
        // whatever
    }
};

Таким образом, HandleTimer может все еще использоваться от функций C, просто удостоверьтесь, что всегда передали "реальный" объект как "пустой* Аргумент"

40
ответ дан Joao da Silva 16 October 2019 в 08:17
поделиться

У Вас есть определенный конфликт здесь в Вашем вопросе. Когда Вы передаете &TimerEvent::TimerHandler библиотеке C, Вы делаете точно это. Вы, возможно, также передали &DerivedTimerEvent::TimerHandler, если Вы хотели. Но Вы не можете передать &TimerEvent::TimerHandler и ожидать библиотека C (!) выяснять, что Вы на самом деле имели в виду &DerivedTimerEvent::TimerHandler.

0
ответ дан MSalters 16 October 2019 в 08:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: