Функция шаблона, принимающая указатель на член, отказывается компилироватьсяC++

Программы на C++. Форум разработчиков
Anonymous
Функция шаблона, принимающая указатель на член, отказывается компилироваться

Сообщение Anonymous »

Рассмотрим этот класс:

Код: Выделить всё

template 
struct Buffer {
template 
int add_member_attribute(
std::string&& name,
Field T::* member_ptr)
{
// ...
return 0;
}
};

struct Thing {
int x;
double y;
};

int main() {
Buffer bt;
Buffer bf;
bt.add_member_attribute("y", &Thing::y);
}
Если T не является типом класса, компилятор выдает сообщение:

Код: Выделить всё

buffer.h:313:22: error: member pointer refers into non-class type 'float'
Field T::* member_ptr,
^
fixture.h:78:22: note: in instantiation of template class 'Buffer' requested here
return f_real->items.data() + 32 * i;
^
Для меня это неожиданно, потому что ни один код даже не пытается вызвать функцию, когда T не является классом. Кажется, ошибка генерируется слишком рано; почему SFINAE не предотвращает это?
Защита add_member_attribute с помощью требует std::is_class_v не позволяет избежать проблемы.Я пробовал написать вспомогательный класс со специализацией шаблона, в том числе с руководствами по дедукции, в надежде использовать SFINAE, чтобы не дать компилятору «увидеть» оскорбительное выражение типа:

Код: Выделить всё

template 
struct MemberPointer {
template 
MemberPointer(const U&) {} // no op
};

template 
requires std::is_class_v
struct MemberPointer {
using type = Field Class::*;

type value;

MemberPointer(type value): value(value) {}

operator type() const {
return value;
}
};

// deduction guides
template 
MemberPointer(Field Class::* v) -> MemberPointer;

template 
MemberPointer(T t) -> MemberPointer;

template 
struct Buffer {
template 
int add_member_attribute(
std::string&& name,
MemberPointer member_ptr)
{
// ...
}
};
Вместо этого это предотвращает сопоставление типа существующим функциям:

Код: Выделить всё

cards.h:70:16: error: no matching member function for call to 'add_member_attribute'
cards->add_member_attribute(PrimitiveVariable::BOUND, &Card::extents);
~~~~~~~^~~~~~~~~~~~~~~~~~~~
buffer.h:311:19: note: candidate template ignored: could not match 'MemberType' against 'range2 behold::Card::*'
AttributeInfo add_member_attribute(
Как объявить эту функцию, чтобы T мог быть типом, не относящимся к классу?
(I' использую Apple Clang 15.0.)

Подробнее здесь: https://stackoverflow.com/questions/786 ... to-compile

Вернуться в «C++»