Skip to content

Conversation

@StephanTLavavej
Copy link
Member

Fixes #1638.

Ordinarily, member functions of a class template are instantiated "on demand" when they're called. (I always remember this as being what allows list<T> to not require operator< from T, unless and until list<T>::sort() is called.) However, if a user derives from a Standard class template, and then __declspec(dllexport)s their derived class, all of the member functions of the Standard class template must be instantiated.

This is how #423 caused a regression in VS 2019 16.6. _Hash::_Multi_equal() is called only for multi containers (unordered_multimap and unordered_multiset), so it static_asserts that _Traits::_Multi is true. However, dllexport can attempt to instantiate this for the unique containers (unordered_map and unordered_set).

There are several possible fixes, but I felt that the least invasive was to make _Multi_equal() a member function template. That alone would be sufficient (i.e. template <int = 0> would work), but constraining it to exist for multi containers is simple. I left the static_assert alone, as it provides a bit of an explanation, even though it is redundant with the constraint now.

I am also adding a regression test, as this is an uncommon but recurring headache in the containers. This covers all of the containers, container adaptors, and views in the Containers clause - which are the most likely to be affected, as they sometimes have conditionally activated code like this. In theory, this test could be extended to cover any Standard type; if we encounter problems in the future, it is easy to extend, but right now having something is better than nothing.

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Feb 11, 2021
@StephanTLavavej StephanTLavavej requested a review from a team as a code owner February 11, 2021 04:04
@StephanTLavavej StephanTLavavej self-assigned this Feb 12, 2021
error C3389: __declspec(dllexport) cannot be used with /clr:pure or /clr:safe
@StephanTLavavej
Copy link
Member Author

Changed the usual_matrix to the impure_matrix because the MS-internal mirror failed with error C3389: __declspec(dllexport) cannot be used with /clr:pure or /clr:safe.

@StephanTLavavej StephanTLavavej merged commit 7f08bb3 into microsoft:main Feb 12, 2021
@StephanTLavavej StephanTLavavej deleted the multi_equal branch February 12, 2021 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

<xhash>: dllexport emits error C2338: This function only works with multi containers

3 participants