LINUX.ORG.RU

Реализуема ли такая конструкция

 


0

1

Хочется сделать одну шаблонную функцию (header.h), которая реализована
различными способами в source1.cpp или source2.cpp.
В зависимости от моего выбора, программа будет собираться с первым или со вторым.
И все это потом вызывать в mainsource.cpp.

//header.h
template <typename T>
  void swap(size_t n, T* x, T* y);

//source1.cpp
template <typename T>
  void swap(size_t n, T* x, T* y){
...
}

//source2.cpp
template <typename T>
  void swap(size_t n, T* x, T* y){
...
}

//mainsource.cpp
int main() {
  swap(...);
  return 0;
}

Реализуема ли такая конструкция?

★★★★★

Нолик заменять на единичку или придумать макрос, который можно менять в настройках проекта, например.

//header.h
template <typename T>
  void swap(size_t n, T* x, T* y);

#if 0
#include "source1.cpp"
#else
#include "source2.cpp"
#endif

//source1.cpp
template <typename T>
  void swap(size_t n, T* x, T* y){
...
}

//source2.cpp
template <typename T>
  void swap(size_t n, T* x, T* y){
...
}

//mainsource.cpp
int main() {
  swap(...);
  return 0;
}

quiet_readonly ★★★★
()

Ещё один засовывает код шаблонной функции в cpp? Ещё вчера же был тред. Нечто подобное можно с помощью частичной специализации накостылить: добавить целочисленный параметр шаблона и сделать несколько специализаций в зависимости от числа.

imtw
()

макросы или системе сборки подсовывать только нужный файл.

Belkrr
()
Ответ на: комментарий от imtw

Ещё один засовывает код шаблонной функции в cpp?

Это естественное желание, но так не сделаешь :(

Как вариант я пока придумал засунуть код в *.h, а для конкретного типа данных переопределить в *.cpp.

template <double> void swap(size_t n, double* x, double* y){ ... }

Zodd ★★★★★
() автор топика

Начнём с того, что шаблоны объявляются целиком в хедерах, поэтому оставьте просто header.h и в нём поместите обе реализации swap под нужными #ifdef.

Либо, что правильнее и плюсовее, дополнительно параметризируйте свой swap классом, реализующим различия - так можно будет использовать обе версии функции сразу. Дефолтную можно определить опять таки макросом.

Как-то так:

//header.h
struct foo_memcpy { static void memcpy(...) {} };
struct bar_memcpy { static void memcpy(...) {} };

template <class M, typename T>
void swap(size_t n, T* x, T* y) {
  M::memcpy(...);
}

template <typename T>
void swap(size_t n, T* x, T* y) {
#ifdef USE_FOO
    swap<foo_memcpy, T>(n, x, y);
#else
    swap<bar_memcpy, T>(n, x, y);
#endif
}

// main.cpp
int main() {
    int x, y;
    swap(1, &x, &y);
    swap<foo_memcpy>(1, &x, &y);
    swap<bar_memcpy>(1, &x, &y);
}
slovazap ★★★★★
()
Ответ на: комментарий от slovazap

шаблоны объявляются целиком в хедерах

Совершенно не обязательно, ничто не мешает определить шаблон внутри .cpp, если нигде больше он использоваться не будет

Gvidon ★★★★
()
Ответ на: комментарий от Zodd

а для конкретного типа данных переопределить в *.cpp

а зачем переопределять?

nanoolinux ★★★★
()
Ответ на: комментарий от imtw

Это понятно(только вот нет другого языка с подобным набором средств построения абстракции, принципом нулевой стоимости и без потери контроля за исполнением, так что приходиться кушать кактус).

Непонятно, зачем вы тогда интересуетесь специализацией шаблонов функций?

anonymous
()
Ответ на: комментарий от anonymous

Ты хочешь какую-то херню. Зачем тебе?

Например, если я захочу подрубить cuda вместо обычной реализации.

Zodd ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Это понятно(только вот нет другого языка с подобным набором средств построения абстракции, принципом нулевой стоимости и без потери контроля за исполнением, так что приходиться кушать кактус).

Вроде D позиционировал себя как продуманную замену крестам, но что-то у них, похоже, плохо всё там. Для прикладного софта вместо крестов удобно использовать чистый си для тонких мест + высокоуровневый язык.

Непонятно, зачем вы тогда интересуетесь специализацией шаблонов функций?

По старой памяти.

imtw
()
Ответ на: комментарий от Google-ch

Я этот язык не смотрел, знаю только, что его пилит Александреску. Ходят слухи, что этот язык сырой, компилятор иногда глючит, у него две несовместимые стандартные библиотеки. OpenMW, например, перекатился взад на кресты.

imtw
()
Ответ на: комментарий от imtw

Да, с D все печально... На Rust пока надеюсь, но это еще несколько лет до выхода...

Сишечка невыносима, если уже знаешь кресты.

anonymous
()
Ответ на: комментарий от anonymous

Сишечка невыносима, если уже знаешь кресты.

Совсем уж чистый си я тоже не использую, просто интерфейс предпочтительнее делать на нём. Иначе возможны неудобства с FFI. Зависит от языка, к которому всё это подключать.

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

imtw
()

вообще шаблоны прописываются в хидерах. Шаблон это такая херня которая генерирует код, в том месте где используется, это что-то похожее на макрос тока круче. короче в исходниках шаблоны не пишут, тока в хидерах

ЗЫ. если захочется иметь разную реализацию. Зачем шаблон? Делай тогда виртуальный метод swap у класса, либо придумай так, что бы шаблон был един, и работал для разных классов.

pozitiffcat ★★★
()
Последнее исправление: pozitiffcat (всего исправлений: 1)
Ответ на: комментарий от imtw

Да ну, с D не настолько всё плохо. Несовместимые стандартные библиотеки были в D1, поддержка которого уже прекратилась. Сейчас одну переписали, другую портировали на D2, так что их можно вместе юзать при желании. Рабочих компиляторов три штуки (DMD, LDC, GDC), последний сейчас пытаются протолкнуть в GCC 4.8. Алсо, недавно наскребли на кикстартере $30k на проведение конференции в мае. Пилят всё это толпой на гитхабе, Александреску в основном только пулл-реквесты принимает да языком чешет.

anonymous
()
Ответ на: комментарий от pozitiffcat

Виртуальный метод, который будет дергаться стопицоттыщ раз в вычислительной программе (иначе зачем ему куда) /0

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.