2013-09-12 3 views
3

Скажите, что нужно создать класс C++ с двумя отдельными реализациями (скажем, один для работы на процессоре и на графическом процессоре), и каждый хочет, чтобы это произошло во время компиляции.Выберите между реализациями во время компиляции

Какой шаблон дизайна можно использовать для этого?

+0

Нет шаблон проектирования, необходимый если вы хотите решить во время компиляции. Просто создайте экземпляр нужной реализации. Если вы хотите, чтобы это было сделано путем переключения некоторых «настроек» в исходном файле, вы можете использовать простой шаблон (или ifdef для стиля 'C'). – BartoszKP

+0

Won 't шаблон будет решаться во время выполнения? мог бы привести пример (я согласен с этим в качестве ответа). – nbubis

+0

C++ шаблоны являются объектами времени компиляции. – Omaha

ответ

7

Хорошая книга для чтения: Современный дизайн C++: общие шаблоны программирования и дизайна Прикладные, написанные Андреем Александреску.

Основном он сказал, что вы можете реализовать то, что вы хотите, используя класс на основе политики (своего рода стратегия шаблон, но сделано во время компиляции Беллоу простой пример, показывающий это:.

#include <iostream> 

using namespace std; 

template <typename T> 
struct CPU 
{ 
    // Actions that CPU must do (low level) 
    static T doStuff() {cout << "CPU" << endl;}; 
}; 

template <typename T> 
struct GPU 
{ 
    // Actions that GPU must do (low level) 
    // Keeping the same signatures with struct CPU will enable the strategy design patterns 
    static T doStuff() {cout << "GPU" << endl;}; 
}; 

template <typename T, template <class> class LowLevel> 
struct Processors : public LowLevel<T> 
{ 
    // Functions that any processor must do 
    void process() { 
    // do anything and call specific low level 
    LowLevel<T>::doStuff(); 
    }; 
}; 

int main() 
{ 
    Processors<int, CPU> cpu; 
    Processors<int, GPU> gpu; 

    gpu.process(); 
    cpu.process(); 
} 
2

Если вы хотите принять решения во время компиляции, всегда есть старый режим ожидания: препроцессор. Используйте #ifdef/#endif блоки и аргументы компилятора, чтобы указать нужный код.

3

Для этого вы можете использовать простой шаблон. (К сожалению для сырой реализации, это просто пример)

#include <iostream> 
struct example 
{ 
    void cpu() { std::cout << "Cpu\n"; } 
    void gpu() { std::cout << "Gpu\n"; } 

    template<bool useGpu = true>void go() { gpu(); } 
}; 
template<>void example::go<false>() { cpu(); } 

int main() 
{ 
    example().go<false>(); //<-- Prints 'Cpu' 
    example().go(); // <-- Prints 'Gpu' 
} 
+0

hmm .. что, если у вас было много функций? хав e для создания трех функций для каждой функциональности вместо двух с помощью метода if else – nbubis

+0

В моем примере рассматривается simpy, выбирающий между двумя методами. Для чего вы хотите, чтобы вы хотели бы специализировать класс с несколькими методами в нем. Ответ BartoszKP более ориентирован на то, что вы ищете ... – Jason

+0

@nbubis: вам не нужно писать cpu() и gpu() с полной реализацией в этом примере. Основная функциональность была бы в отдельной функции: она будет вызываться непосредственно из cpu() и вызывается через функцию __kernel__, отправленную на GPU из gpu(). В основном, только бухгалтерия, необходимая для представления GPU, должна быть написана отдельно (они всегда есть); остальные могут быть общими. – Michael

3

Простейшие пример решения, используя Strategy шаблон (однако, это не имеет значения, является ли это время компиляции или во время, выбранное):

class BaseStrategy 
{ 
    public: 
    virtual void doStuff() = 0; 
}; 

class Strategy1 : public Base 
{ 
    public: 
    void doStuff(); 
}; 

class Strategy2 : public Base 
{ 
    public: 
    void doStuff(); 
}; 

class SomeKindOfAMainClass 
{ 
    public: 
    SomeKindOfAMainClass(BaseStrategy* s) 
    { 
     this->s = s; 
    } 
    void doStuff() 
    { 
     s->doStuff(); 
    } 
    private: 
    BaseStrategy* s; 
}; 

, а затем вы просто делаете либо new SomeKindOfAMainClass(new Strategy1()), либо new SomeKindOfAMainClass(new Strategy2()).

Простой пример черты:

struct WithStrategy1 {}; 
struct WithStrategy2 {}; 

template<typename T> 
class SomeKindOfAMainClass; 

template<> 
class SomeKindOfAMainClass<WithStrategy1> 
{ 
    //use Strategy1 here 
}; 

template<> 
class SomeKindOfAMainClass<WithStrategy2> 
{ 
    //use Strategy2 here 
}; 

И вы просто либо экземпляр SomeKindOfAMainClass<WithStrategy1> или SomeKindOfAMainClass<WithStrategy2> в начале программы.

Или у вас может быть решение от Omaha с #ifdef.

Смежные вопросы