Closed playgithub closed 2 years ago
Hi, thanks for the report. I'd need more info to be able to reproduce the error, as tests here for VS 2022 run OK (look for "msvc- 14.3" at https://www.boost.org/development/tests/master/developer/multi_index.html).
Thank you,
Hi, thanks for the report. I'd need more info to be able to reproduce the error, as tests here for VS 2022 run OK (look for "msvc- 14.3" at https://www.boost.org/development/tests/master/developer/multi_index.html).
- Can you provide more info on the environment where you've found the problem?
conan
or vcpkg
(both the same error)Strangely, in Visual Studio 2022 solution which also use vcpkg
, it builds successfully.
- Can you provide a link to the code using Boost.MultiIndex that triggered the compiler error? Even better, can you provide a minimal, complete and verifiable example code showing the problem?
I've written a simple project, but it can't be reproduced, it builds successfully.
It might be a bug for me, so close the issue first, if it is for me, I should reopen it with enough info.
Thanks
Ok, good luck with your project.
Hi Ronald
I received a notification of some additional comment of yours on this issue, but the comment is not appearing online now, maybe you've deleted it?
I received a notification of some additional comment of yours on this issue, but the comment is not appearing online now, maybe you've deleted it?
Yes, when using it with
it doesn't work, but when using it with
it works
So I'm not sure what's the problem.
I'm going to test the former case on Linux.
In a comment that didn't make it online (yet I received via a notification email) you talked about a sample.cpp
file. Would it be possible to take a look at that?
In a comment that didn't make it online (yet I received via a notification email) you talked about a
sample.cpp
file. Would it be possible to take a look at that?
sample.cpp
is just a placeholder , I've tried to write a simple demo, but it can't be reproduced.
BTW, I've tried linux, but it got another problems when do conan install
for boost.
Anyway I'm going to debug it on Windows.
If I find s.th. helpful, I'll post it here.
The problem is caused by __declspec(dllexport)
, if comment it out, there will be no problem.
Anyway to export a class derived from bmi::multi_index_container
on Windows?
#include <memory>
#include <string>
#include <boost/uuid/uuid.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
namespace bmi = boost::multi_index;
class A
{
public:
A(int id, const std::string& name) : __id(id), __name(name) {}
public:
int GetID() const { return __id; }
const std::string& GetName() const { return __name; }
private:
int __id;
std::string __name;
};
struct random_access_index_tag;
struct id_index_tag;
struct name_index_tag;
typedef bmi::multi_index_container<
std::shared_ptr<A>,
bmi::indexed_by<
bmi::random_access<bmi::tag<random_access_index_tag>>,
bmi::hashed_unique<bmi::tag<id_index_tag>, bmi::const_mem_fun<A, int, &A::GetID>>,
bmi::hashed_unique<bmi::tag<name_index_tag>, bmi::const_mem_fun<A, const std::string&, &A::GetName>>
>
> AMultiIndexContainer;
class __declspec(dllexport) AGroup : public AMultiIndexContainer
{
};
In the post https://stackoverflow.com/a/7302165, it says "C++ is not a "pure OOP" and container are not OOP at all.".
Does it mean that in this case it is not well supported to derive from boost::multi_index
?
Your problem has nothing to do with deriving from multi_index_container
(which some may find questionable but is undoubtedly doable). What I think it's happening is the following:
begin
, end
, or insert
) and none of its member function templates (find
, emplace
, etc.) So far so good, you'll have duplicates of member function templates in your EXE and your DLL but that's probably OK.hash_index
has two versions of the non-template member function in_place
, one for unique indices and the other for non-unique indices, which are selected at compile time based on the uniqueness of the index. But the compiler is exporting and, consequently, trying to compile both, and the non-unique version fails because, well, the index is unique.AGroup
class and instead export the member functions of AGroup
individually. This won't export any of the AMultiIndexContainer
member functions, but that shouldn't be a problem except for some code duplication in the EXE and the DLL (your EXE will be bigger).So the problem dues to the functions below when exporting
bool in_place(
node_impl_pointer x,key_param_type k,std::size_t buc,
hashed_unique_tag)const
bool in_place(
node_impl_pointer x,key_param_type k,std::size_t buc,
hashed_non_unique_tag)const
But the compiler is exporting and, consequently, trying to compile both, and the non-unique version fails because, well, the index is unique.
I don't quite understand this, does it mean they have the same function signature to the complier,
and only one can be exported when exporting?
And for static link, it simply works by specializing the template with different template param Category
, right?
It doesn't have to do with the signature, these two are different functions and the problem is that the compiler tries to generate both. Let me explain by way of an example:
template<typename T>
struct AClassTemplate
{
static void call_foo(){T::foo();}
static void call_bar(){T::bar();}
};
struct FooClass
{
static void foo(){}
};
struct __declspec(dllexport) DerivedClass:AClassTemplate<FooClass>
{
void call_foo(){AClassTemplate<FooClass>::call_foo();}
};
int main(){}
This fails because the compiler is trying to export (and compile) AClassTemplate<FooClass>::call_foo
(OK) and AClassTemplate<FooClass>::call_bar
(NOK, FooClass
has no bar
member function to call). On the contrary, the following:
template<typename T>
struct AClassTemplate
{
static void call_foo(){T::foo();}
static void call_bar(){T::bar();}
};
struct FooClass
{
static void foo(){}
};
struct DerivedClass:AClassTemplate<FooClass>
{
void __declspec(dllexport) call_foo(){AClassTemplate<FooClass>::call_foo();}
};
int main(){}
works because we are not compiling every member function of AClassTemplate<FooClass>
, but only those used by the exported function DerivedClass::call_foo
. Clearer now?
Yes, clear now, because specialization of a template is not complete. Thanks very much
Env
Windows Visual Studio 2022 boost 1.78.0 vcpkg C++ 17
Compile Error
Source Code
https://github.com/boostorg/multi_index/blob/9c40dfee82e3c42960e137cd765d7bcb850dc256/include/boost/multi_index/hashed_index.hpp#L1598