Skip to content

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

Description

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 .

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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