如何定义和使用指向 "array" 成员的指针?
How to define and use a pointer to an "array" member?
我有一堆结构,每个结构都有一个 'array' 成员和一个大小指示器:
struct S {
size_t num;
int arr[100];
};
struct V {
float array[10];
int size;
};
我想为每个结构创建操纵器对象:
template <typename Type, typename ElementType, size_t N, typename SizeType>
struct StructManipulator {
Type* resource_;
ElementType Type::*elements[N];
SizeType Type::*sizeIndicator;
void set(ElementType val, size_t idx)
{
resource_->*elements[idx] = val;
}
};
template <typename Type, typename ElementType, size_t N, typename SizeType>
StructManipulator<Type, ElementType, N, SizeType> makeStructManipulator(Type* resource,
ElementType Type::*elements[N], SizeType Type::*sizeIndicator)
{
return StructManipulator<Type, ElementType, N, SizeType>{resource, elements, sizeIndicator};
}
StructManipulator
将允许我独立于数组的偏移量和结构中的大小指示符来操作数组元素。所有 StructManipulator
都是 'array' 在结构中的偏移量,大小指示器的偏移量和类型以及指向结构对象的指针。
但是,当我尝试创建 StructManipulator
:
int main()
{
S s;
auto m = makeStructManipulator(&s, &S::arr, &S::num);
m.set(5, 4);
}
我收到这个错误:
main.cpp: In function 'int main()':
main.cpp:39:56: error: no matching function for call to 'makeStructManipulator(S*, int (S::*)[100], size_t S::*)'
auto m = makeStructManipulator(&s, &S::arr, &S::num);
^
main.cpp:29:51: note: candidate: template<class Type, class ElementType, long unsigned int N, class SizeType> StructManipulator<Type, ElementType, N, SizeType> makeStructManipulator(Type*, ElementType Type::**, SizeType Type::*)
StructManipulator<Type, ElementType, N, SizeType> makeStructManipulator(Type* resource,
^~~~~~~~~~~~~~~~~~~~~
main.cpp:29:51: note: template argument deduction/substitution failed:
main.cpp:39:56: note: mismatched types 'ElementType Type::**' and 'int (S::*)[100]'
auto m = makeStructManipulator(&s, &S::arr, &S::num);
我好像无法正确声明 "pointer to an array member" 的类型?正确的声明应该是什么?
适用于指针声明符的几乎相同的语法规则也适用于指向成员声明符的指针。这意味着 elements
需要这样定义:
ElementType (Type::* elements)[N];
否则你会得到一个指向成员的指针数组,而不是一个指向成员数组的指针。
然后最好将通过它进行的任何访问用括号括起来,就像其他指向用于后缀表达式(例如函数调用)的成员的指针一样:
(resource_->*elements)[idx] = val;
在 C++17 中,可以使用 std::invoke
调用 class 成员(不仅是成员函数),而不是使用 .*
和 ->*
运算符他们不方便的优先规则。
所以,@StoryTeller 的
ElementType (Type::* elements)[N];
你可以通过写
来访问数组
std::invoke(elements, resource_)[idx] = val;
我有一堆结构,每个结构都有一个 'array' 成员和一个大小指示器:
struct S {
size_t num;
int arr[100];
};
struct V {
float array[10];
int size;
};
我想为每个结构创建操纵器对象:
template <typename Type, typename ElementType, size_t N, typename SizeType>
struct StructManipulator {
Type* resource_;
ElementType Type::*elements[N];
SizeType Type::*sizeIndicator;
void set(ElementType val, size_t idx)
{
resource_->*elements[idx] = val;
}
};
template <typename Type, typename ElementType, size_t N, typename SizeType>
StructManipulator<Type, ElementType, N, SizeType> makeStructManipulator(Type* resource,
ElementType Type::*elements[N], SizeType Type::*sizeIndicator)
{
return StructManipulator<Type, ElementType, N, SizeType>{resource, elements, sizeIndicator};
}
StructManipulator
将允许我独立于数组的偏移量和结构中的大小指示符来操作数组元素。所有 StructManipulator
都是 'array' 在结构中的偏移量,大小指示器的偏移量和类型以及指向结构对象的指针。
但是,当我尝试创建 StructManipulator
:
int main()
{
S s;
auto m = makeStructManipulator(&s, &S::arr, &S::num);
m.set(5, 4);
}
我收到这个错误:
main.cpp: In function 'int main()':
main.cpp:39:56: error: no matching function for call to 'makeStructManipulator(S*, int (S::*)[100], size_t S::*)'
auto m = makeStructManipulator(&s, &S::arr, &S::num);
^
main.cpp:29:51: note: candidate: template<class Type, class ElementType, long unsigned int N, class SizeType> StructManipulator<Type, ElementType, N, SizeType> makeStructManipulator(Type*, ElementType Type::**, SizeType Type::*)
StructManipulator<Type, ElementType, N, SizeType> makeStructManipulator(Type* resource,
^~~~~~~~~~~~~~~~~~~~~
main.cpp:29:51: note: template argument deduction/substitution failed:
main.cpp:39:56: note: mismatched types 'ElementType Type::**' and 'int (S::*)[100]'
auto m = makeStructManipulator(&s, &S::arr, &S::num);
我好像无法正确声明 "pointer to an array member" 的类型?正确的声明应该是什么?
适用于指针声明符的几乎相同的语法规则也适用于指向成员声明符的指针。这意味着 elements
需要这样定义:
ElementType (Type::* elements)[N];
否则你会得到一个指向成员的指针数组,而不是一个指向成员数组的指针。
然后最好将通过它进行的任何访问用括号括起来,就像其他指向用于后缀表达式(例如函数调用)的成员的指针一样:
(resource_->*elements)[idx] = val;
在 C++17 中,可以使用 std::invoke
调用 class 成员(不仅是成员函数),而不是使用 .*
和 ->*
运算符他们不方便的优先规则。
所以,@StoryTeller 的
ElementType (Type::* elements)[N];
你可以通过写
来访问数组std::invoke(elements, resource_)[idx] = val;