2

我有一堆结构,每个结构都有一个“数组”成员和一个大小指示器:

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是结构中“数组”的偏移量、大小指示符的偏移量和类型以及指向结构对象的指针。

但是,当我尝试创建一个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);

我看起来无法正确声明“指向数组成员的指针”的类型?正确的声明应该是什么?

4

2 回答 2

3

适用于指针声明符的几乎相同的语法规则也适用于指向成员声明符的指针。这意味着elements需要像这样定义:

ElementType (Type::* elements)[N];

否则,您会得到一个指向成员的指针数组,而不是指向成员数组的指针。

然后你最好用括号括起来通过它进行的任何访问,因为你应该使用其他指向用于后缀表达式的成员的指针(例如函数调用):

(resource_->*elements)[idx] = val;
于 2018-01-23T06:33:22.963 回答
2

在 C++17 中,您可以使用std::invoke来调用类成员(不仅是成员函数),而不是使用带有不便的优先级规则的.*and运算符。->*

所以,对于@StoryTeller 的

ElementType (Type::* elements)[N];

您可以通过编写访问数组

std::invoke(elements, resource_)[idx] = val;
于 2018-01-23T08:22:28.293 回答