Reputation: 3565
Suppose I have a class X
with private implementation Ximpl
:
//Proj.h
#ifdef PROJ_EXPORTS
#define PROJ_API __declspec(dllexport)
#else
#define PROJ_API __declspec(dllimport)
#endif
//X.h
class PROJ_API X
{
void foo();
//..
private:
class Ximpl;
std::unique_ptr<Ximpl> x_impl;
}
This works perfectly, but generates the warning:
Compiler Warning (level 1) C4251:
warning C4251: 'X::Ximpl' : class 'std::unique_ptr>' needs to have dll-interface to be used by clients of class 'X::Ximpl'
I have tried to follow the suggested MSDN article, but 1). it didn't work. 2) I don't clearly understand the solution(workaround)
Any advice/explanation on how to get rid of these warnings (#pragma disable's are not an option :) ).
Why is it Level 1 warning?
NOTE: It turns out that if Ximpl
is not declared in X
scope, then it's possible to export a unique_ptr<Ximpl>
after forward-declaration of Ximpl
, but if it's in X
s scope, then it's a nested class and therefore can't be forward-declared..
However, for templated class even above solution (have non-nested impl class), seems to fail:
//X.h
template<typename T>
class PROJ_API X
{
T foo();
//..
private:
class Ximpl;
std::unique_ptr<Ximpl> x_impl;
}
Upvotes: 2
Views: 1225
Reputation: 1821
Make sure your class X exports and declares non-inlined destructor. Otherwise the compiler implicitly declares inline destructor, which needs to know something about Ximpl in order to call its destructor. And with inline destructor, users of X also need to know how to destroy std::unique_ptr, which leads to the warning.
You can confirm this by checking that ~Ximpl() isn't called when X gets deleted, unless you export non-inlined ~X().
Upvotes: 2