Я хочу, чтобы функция шаблона bar вызывала функцию шаблона foo с квалификатором const .
У меня есть два шаблона для функций foo и bar с их экземплярами.Это foo.cpp
#include "foo.h"
#include <iostream>
template <class T>
void foo(const T x){
std::cout<<x[0]<<std::endl;
};
// instantiation here, in order to avoid implementation in header
template void foo<const int*>(const int*);
foo.h :
template <class T>
void foo(T x);
bar.cpp :
#include "bar.h"
#include "foo.h"
#include <iostream>
template <class T>
void bar(T x){
foo<const T>(x);
};
// instantiation here, in order to avoid implementation in header
template void bar<int*>(int*);
и bar.h :
template <class T>
void bar(T x);
наконец, main.cpp :
#include <iostream>
#include "bar.h"
#include "foo.h"
int main()
{
int p[5];
p[0]=17;
foo(p);
bar(p);
return 0;
}
Все.h файлы содержат # ifndef / # определяют стандартные операторы.Функция foo должна получить массив int s, а не изменять его, поэтому в ней есть квалификатор const .Я хочу, чтобы функция bar получила массив int s и изменила его, в какой-то момент она также должна вызвать функцию foo .Причина использования шаблона заключается в том, что в будущем я хочу вызывать эти функции для различных типов данных, таких как double *, std :: vector & и т. Д.
Когда я пытаюсь скомпилировать, я получаю следующую ошибку:
undefined reference to `void foo<int* const>(int* const)'
, как будто он не может привести int * к const int *,Кроме того, он, кажется, заменяет указатель на const int на const указатель на int.Любая идея, как я могу справиться с этим?
Еще одно наблюдение: если я удаляю foo.cpp и bar.cpp и вместо этого сливаю все в один файл, который он компилируетобычно.
=========================================
Дело решено
Реализация для foo выполнена для .Как заметили люди, когда foo вызывается в bar , const T приводится к T const == int * const , что не являетсятак же, как const int *.
Чтобы превратить его в int const *, я добавил к коду:
typedef typename std::remove_pointer<T>::type tmp_type; // tmp_type = int
foo<tmp_type const *>(x);
Youнужно -std = c ++ 11, чтобы скомпилировать это.В качестве альтернативы, как предложил Дэвис Херринг, вы можете вместо этого использовать
foo<const std::remove_pointer_t<T>*>(x);
, но для этого вам нужно будет использовать -std = c ++ 14.
Проблема не имеет ничего общего среализация шаблонов в заголовочном файле, за исключением очевидного наблюдения, что ничего этого не требуется, если все находится в одном файле.
Другое решение состоит в том, чтобы иметь два экземпляра для foo:
template void foo<int const *>(int const *);
template void foo<int *>(int *);
где первый не позволяет вам изменить значение указателя внутри функции, а второй позволяет вам передать в него просто int *.