#c
#c
Вопрос:
Я пытаюсь реализовать статическую функцию в исходном файле cpp. Получить ошибку переопределения. Может кто-нибудь мне помочь? Большое спасибо!
DEFINE_MY_STATIC_PTR(B_type)
DEFINE_MY_STATIC_PTR(A_type)
— ошибка: переопределение
struct A_type : B_type
{}
#define DEFINE_MY_STATIC_PTR( TYPE )
template< typename TYPE >
My_self_deleting* My_static_ptr<TYPE>::my_self_deleting_ptr( TYPE* ptr )
{ return ptr; }
template<typename TYPE>
struct My_static_ptr : My_pointer
{
static My_self_deleting* my_self_deleting_ptr ( TYPE* );
}
Как правильно выполнить такое определение?
Из всей справки я обнаружил, что он должен удалить приведенный выше шаблон. При использовании это станет реализацией для каждого типа.
#define DEFINE_MY_STATIC_PTR( TYPE )
My_self_deleting* My_static_ptr<TYPE>::my_self_deleting_ptr( TYPE* ptr )
{ return ptr; }
DEFINE_MY_STATIC_PTR(B_type)
error: too few template-parameter-lists
Должен ли я добавить что-то еще к этому определению макроса?
Да, добавить шаблон <>
#define DEFINE_MY_STATIC_PTR( TYPE )
template <>
My_self_deleting* My_static_ptr<TYPE>::my_self_deleting_ptr( TYPE* ptr )
{ return ptr; }
Комментарии:
1. вы уверены, что поняли механизм шаблона?
2. Какова цель этого макроса? Почему бы вам просто не использовать шаблоны так, как они предназначены?
3. Я учусь писать код с шаблоном, и этот код — это то, что я вижу из другой библиотеки. Я думаю, это просто. Создает ли этот макрос проблемы с получением этой ошибки?
4. Мы не можем сказать вам, «как правильно выполнить такое определение», если вы не скажете нам, чего вы пытаетесь достичь.
5. определение DEFINE_MY_STATIC_PTR по-прежнему включает переопределение оператора, например : ::operate= и т. Д. Итак, чтобы избежать дублирования этого кода везде с разницей только в типах. Макрос предназначен для этой цели.
Ответ №1:
Я не совсем уверен, что вы пытаетесь сделать, но позвольте мне сделать несколько общих замечаний:
У вас нет класса, у вас есть шаблон класса. Это означает, что вы обычно не можете отделить реализацию от определения, поскольку определение должно быть видно в каждой точке, где вы создаете экземпляр шаблона. Таким образом, типичным решением было бы поместить все в заголовок:
// header.hpp
template<typename T>
struct My_static_ptr : My_pointer
{
static My_self_deleting * my_self_deleting_ptr(T * p)
{
return p;
}
};
Только в определенных особых ситуациях вы могли бы рассмотреть альтернативу предоставления ограниченного набора явных экземпляров шаблонов:
// header.hpp
template<typename T>
struct My_static_ptr : My_pointer
{
static My_self_deleting * my_self_deleting_ptr(T * p);
};
// implementation.cpp
template<typename T> My_self_deleting * My_static_ptr<T>::my_self_deleting_ptr(T * p)
{
return p;
}
// Only the following specializations are usable in your entire program!
template struct My_static_ptr<int>;
template struct My_static_ptr<double>;
template struct My_static_ptr<Foo>;
Ответ №2:
В принципе, механизм шаблонов можно использовать, чтобы избежать перезаписи одного и того же алгоритма для разных типов.
Добавление макроса для объявления нескольких шаблонов приводит к переопределению шаблона.
В вашем случае достаточно единственного объявления метода шаблона. Вот как должен выглядеть ваш код:
// declaration of struct A_type
struct A_type : B_type
{}
// declaration of template class My_static_ptr, of template parameter TYPE
template<typename TYPE>
struct My_static_ptr : My_pointer
{
// declaration of template method my_self_deleting_ptr, of template parameter TYPE
static My_self_deleting* my_self_deleting_ptr ( TYPE* );
}
// definition of template static method my_self_deleting_ptr, of template parameter TYPE
template< typename TYPE >
My_self_deleting* My_static_ptr<TYPE>::my_self_deleting_ptr( TYPE* ptr )
{ return ptr; }
Затем вам нужно создать экземпляр вашего шаблона с конкретным типом, чтобы вы могли его использовать:
// instantiation of the template for A_type, by creating an object My_static_ptr parameterized with A_type
My_static_ptr< A_type > myStaticPointer_of_A_type;
Комментарии:
1. Большое спасибо всем, кто выше, за попытку ответить на мой вопрос.
Ответ №3:
Чтобы уточнить, почему эта конкретная ошибка, когда компилятор видит (ну, в данном случае препроцессор):
DEFINE_MY_STATIC_PTR(B_type)
DEFINE_MY_STATIC_PTR(A_type)
Он применяет макрос и выполняет текстовую замену аргументов макроса, заканчивающуюся:
template< typename B_type >
My_self_deleting* My_static_ptr<B_type>::my_self_deleting_ptr( B_type* ptr )
{ return ptr; }
template< typename A_type >
My_self_deleting* My_static_ptr<A_type>::my_self_deleting_ptr( A_type* ptr )
{ return ptr; }
Хотя для вас A_type
и B_type
, вероятно, означают типы с таким именем, для компилятора они являются просто идентификаторами как T
или U
. Таким образом, этот код в точности эквивалентен:
template< typename T >
My_self_deleting* My_static_ptr<T>::my_self_deleting_ptr( T* ptr )
{ return ptr; }
template< typename T >
My_self_deleting* My_static_ptr<T>::my_self_deleting_ptr( T* ptr )
{ return ptr; }
И там у вас есть несколько определений: Вы дважды определили my_self_deleting_ptr
функцию-член шаблона класса в одной и той же единице перевода, что является ошибкой, даже если оба определения в точности эквивалентны.
Комментарии:
1. Большое спасибо за то, что вы помогли мне с этим делом. Все это дало мне хорошую базу знаний, чтобы разобраться в этом. Этот фрагмент кода взят из сторонней библиотеки и должен передаваться со старым компилятором gcc. Если я закомментирую одно из определений, это даст мне неопределенную неопределенную ссылку на ошибку ссылки `MY_Class::My_static_ptr<My_Class:: A_type>::operator= (MY_Class:: A_type *)’ со ссылкой. Все еще посмотрите на код и дадим более подробную информацию.