Код: Выделить всё
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);
}
Код: Выделить всё
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;
^
Защита 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(
(I' использую Apple Clang 15.0.)
Подробнее здесь: https://stackoverflow.com/questions/786 ... to-compile