Mark ArrayHandle constructors taking buffers, as explicit

This resolves a compiler ambiguity I hit during development.
In my case, I created an `ArrayHandleDecorator` with one of the arrays being
an `ArrayHandleTransform`. The ambiguity occurs in function
`DecoratorStorageTraits<...>::BuffersToArray`, here an `ArrayHandleTransform`
is constructed using buffers (`std::vector<vtkm::cont::internal::Buffer>`)

This constructor is not defined for `ArrayHandleTransform`, but it's defined for
its superclass (`vtkm::cont::ArrayHandle`). `ArrayHandleTransform` does have a
non-explicit constructor that takes the array to be transformed and the
transform-functor as parameters, where the later has a default value.
This produces the following ambiguous options for the compiler:

1. Create a "to-be-transformed" ArrayHandle instance using the buffers, call
   the `ArrayHandleTransform` constructor with this array with the defaulted
   functor parameter.
2. Create the superclass instance using the buffer and call the
  `ArrayHandleTransform` constructor that takes the superclass.

In this situation, option 2 is the correct choice.

The ambiguity is resolved by marking the constructors that take
buffers as explicit. These constructors are also added for the
derived classess via the `VTK_M_ARRAY_HANDLE_SUBCLASS_IMPL` macro.
This commit is contained in:
Sujin Philip 2023-06-05 09:21:12 -04:00
parent 845ddd6572
commit fc9077e0c5
3 changed files with 17 additions and 5 deletions

@ -186,6 +186,18 @@ struct GetTypeInParentheses<void(T)>
} \
\
VTKM_CONT \
explicit classname(const std::vector<vtkm::cont::internal::Buffer>& buffers) \
: Superclass(buffers) \
{ \
} \
\
VTKM_CONT \
explicit classname(std::vector<vtkm::cont::internal::Buffer>&& buffers) noexcept \
: Superclass(std::move(buffers)) \
{ \
} \
\
VTKM_CONT \
Thisclass& operator=(const Thisclass& src) \
{ \
this->Superclass::operator=(src); \
@ -332,12 +344,12 @@ public:
/// Special constructor for subclass specializations that need to set the
/// initial state array. Used when pulling data from other sources.
///
VTKM_CONT ArrayHandle(const std::vector<vtkm::cont::internal::Buffer>& buffers)
VTKM_CONT explicit ArrayHandle(const std::vector<vtkm::cont::internal::Buffer>& buffers)
: Buffers(buffers)
{
}
VTKM_CONT ArrayHandle(std::vector<vtkm::cont::internal::Buffer>&& buffers) noexcept
VTKM_CONT explicit ArrayHandle(std::vector<vtkm::cont::internal::Buffer>&& buffers) noexcept
: Buffers(std::move(buffers))
{
}

@ -230,11 +230,11 @@ public:
static FirstArrayType GetFirstArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return { FirstArrayBuffers(buffers) };
return FirstArrayType(FirstArrayBuffers(buffers));
}
static SecondArrayType GetSecondArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return { SecondArrayBuffers(buffers) };
return SecondArrayType(SecondArrayBuffers(buffers));
}
};
} // namespace internal

@ -320,7 +320,7 @@ static void TestIndexing()
vtkm::cont::CellSetStructured<3> outCellSet;
outCellSet.SetPointDimensions({ outDim });
vtkm::cont::ArrayHandleUniformPointCoordinates inField{ { inDim } };
vtkm::cont::ArrayHandleUniformPointCoordinates inField(vtkm::Id3{ inDim });
vtkm::cont::ArrayHandle<vtkm::Vec3f> outField;