Для реализации интерфейса, который принимает функцию обратного вызова и параметр,
Ex.
template<class T_class_type, class T_data_type>
class Some_interface
{
public:
Some_interface(T_class_type* inst, void (T_class_type::*func)(T_data_type));
void add(const T_data_type& data);
private:
void call(const T_data_type& data);
};
, где T_data_type
может быть любого типа и иметь квалификаторы const
и &
, у меня проблема, когда форма [T_data_type] = const T_data_type&
. Например, в функции add()
это расширилось бы до add(const const T_data_type&& data)
. Очевидная ошибка компилятора. Однако причина, по которой мы передаем постоянные ссылки, заключается в том, чтобы уменьшить ненужное копирование данных. Во всяком случае, чтобы решить эту проблему, я реализовал следующее,
template<class T_data_type>
struct No_qualifiers
{
typedef T_data_type Type;
};
template<class T_data_type>
struct No_qualifiers<T_data_type&>
{
typedef T_data_type Type;
};
template<class T_data_type>
struct No_qualifiers<const T_data_type>
{
typedef T_data_type Type;
};
template<class T_data_type>
struct No_qualifiers<const T_data_type&>
{
typedef T_data_type Type;
};
template<class T_class_type, class T_data_type>
class Some_interface
{
public:
Some_interface(T_class_type* inst, void (T_class_type::*func)(T_data_type));
void add(const typename No_qualifiers<T_data_type>::Type& data);
private:
void call(const T_data_type& data);
};
Частичная специализация в моих тестах удаляет нежелательные квалификаторы, которые пользователь интерфейса мог ошибочно передать в параметр шаблона.
Используя это на практике, я нахожу ошибки, которые не могу объяснить. Я был бы признателен за новый набор глаз, которые могут быть в состоянии увидеть предостережения при таком подходе.
Некоторые условия, которые у меня есть, состоят в том, что я не могу изменить способ, которым пользователи вызывают интерфейс, и я использую более старый стандарт с 2003 года. Ошибка, которую я сейчас отлаживаю, я полагаю, связана с typename
, используемым в коде пользователя как Что ж; возможно, передача неразрешенного типа в add()
, что также не разрешено, поэтому компилятор не может найти подходящую функцию для вызова.
Edit:
Таким образом, проблема "typename", с которой я столкнулся, была ошибкой кодирования, не связанной с вопросом. Кроме того, я обнаружил, что удаление спецификатора const
не нужно, нужно удалить только &
.
Спасибо за ответы.