Skip to content

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

@StephanTLavavej

Description

@StephanTLavavej
C:\Temp>type meow.cpp
#include <unordered_set>
using namespace std;

struct __declspec(dllexport) SymTbl : unordered_set<int> {};
C:\Temp>cl /EHsc /nologo /W4 /MD /std:c++17 /c /wd4251 meow.cpp
meow.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.28.29828\include\xhash(1996): error C2338: This function only works with multi containers
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.28.29828\include\xhash(1995): note: while compiling class template member function 'bool std::_Hash<std::_Uset_traits<_Kty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::_Multi_equal(const std::_Hash<std::_Uset_traits<_Kty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>> &) const'
        with
        [
            _Kty=int,
            _Hasher=std::hash<int>,
            _Keyeq=std::equal_to<int>,
            _Alloc=std::allocator<int>
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.28.29828\include\unordered_set(65): note: see reference to class template instantiation 'std::_Hash<std::_Uset_traits<_Kty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>' being compiled
        with
        [
            _Kty=int,
            _Hasher=std::hash<int>,
            _Keyeq=std::equal_to<int>,
            _Alloc=std::allocator<int>
        ]
meow.cpp(4): note: see reference to class template instantiation 'std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>' being compiled

This is because we have:

STL/stl/inc/xhash

Lines 1844 to 1845 in 47cd703

_NODISCARD bool _Multi_equal(const _Hash& _Right) const {
static_assert(_Traits::_Multi, "This function only works with multi containers");

called by only:

STL/stl/inc/xhash

Lines 1949 to 1950 in 47cd703

if constexpr (_Traits::_Multi) {
return _Left._Multi_equal(_Right);

The Standard says that _Multi_equal() will be instantiated "on demand" only when it's called, but dllexport tries to instantiate all non-template member functions.

Exporting classes that derive from STL containers isn't exactly recommended, but we should avoid this code pattern that causes compiler errors.

Reported as DevCom-1319981 and Microsoft-internal VSO-1270072 / AB#1270072 .

Metadata

Metadata

Labels

bugSomething isn't workingfixedSomething works now, yay!

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions