Why doesn't this C++ template code compile? - c++

Does anyone know why this will not compile? I've tried both VS 2008 and GCC 4.something and both spit out errors. It doesn't matter whether or not I'm referencing "ThisFunctionDoesNotCompile()".
I can workaround this by just passing 'InternalType' as a second template parameter to Base, but I'm still curious why this comes up as an error.
#include <iostream>
using namespace std;
class DataClass
{
public:
int m_data;
};
template<typename DerivedType>
class Base
{
public:
int ThisFunctionCompiles()
{
// No problems here.
typename DerivedType::InternalType temp;
temp.m_data = 5;
return temp.m_data;
}
// error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>'
typename DerivedType::InternalType ThisFunctionDoesNotCompile()
{
return static_cast<DerivedType*>(this)->GetInternalData();
}
};
template<typename InInternalType>
class Derived : public Base<Derived<InInternalType> >
{
public:
typedef InInternalType InternalType;
InternalType GetInternalData()
{
return m_internalData;
}
private:
InternalType m_internalData;
public:
void SetInternalData( int newVal )
{
m_internalData.m_data = newVal;
}
};
int main()
{
Derived<DataClass> testDerived;
testDerived.SetInternalData( 3 );
cout << testDerived.GetInternalData().m_data << endl;
cout << testDerived.ThisFunctionCompiles() << endl;
// The compiler gives an error regardless of whether or not this is commented out.
//cout << testDerived.ThisFunctionDoesNotCompile().m_data << endl;
return 0;
}
These are the errors I get in VS 2008:
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>'
1> with
1> [
1> InInternalType=DataClass
1> ]
1> e:\test\generaltestprogram\generaltestprogram\main.cpp(35) : see reference to class template instantiation 'Base<DerivedType>' being compiled
1> with
1> [
1> DerivedType=Derived<DataClass>
1> ]
1> e:\test\generaltestprogram\generaltestprogram\main.cpp(58) : see reference to class template instantiation 'Derived<InInternalType>' being compiled
1> with
1> [
1> InInternalType=DataClass
1> ]
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2146: syntax error : missing ';' before identifier 'ThisFunctionDoesNotCompile'
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : warning C4183: 'ThisFunctionDoesNotCompile': missing return type; assumed to be a member function returning 'int'
And these are what GCC gives me:
main.cpp: In instantiation of 'Base<Derived<DataClass> >':
main.cpp:96: instantiated from 'Derived<DataClass>'
main.cpp:119: instantiated from here
main.cpp:88: error: no type named 'InternalType' in 'class Derived<DataClass>'

At the time that the templated class Base is instantiated as a parent of the class Derived, the class Derived is not a complete type.
Since Base<Derived<DataClass> > is a parent class of Derived<DataClass>, it must be instantiated before Derived<DataClass> can be instantiated. So when the class Base<Derived<DataClass> > is built from the template, Derived<DataClass> behaves as if it were a forward declaration. And as you're probably aware, you can't reference members of incomplete types, nor can your forward-declare nested types, so you're out of luck here.
This, by the way, is why it's difficult to implement a properly covariant clone() method using templates. See here and here (mine).

Related

Game Engine SFML in C++ Errors

This is a Game Engine for SFML builded in c++. I get some errors that i don't know how to fix it. If someone can solve this problem i will apriciated a lot.
I'm still learning c so por someone could same an obious problem or solucion but i just copied the code from another page and I do exactly the same and mine code isn't working
Errors:
Error C2065: 'StateSystem' : undeclared identifier
Error C2923: 'std::unique_ptr' : 'StateSystem' is not a valid template type
argument for parameter '_Ty'
Error C3203: 'unique_ptr' : unspecialized class template can't be used as a
template argument for template parameter '_Ty', expected a real type
Error C2512: 'std::unique_ptr' : no appropriate default constructor
available
Error C2780: '_OutTy *std::move(_InIt,_InIt,_OutTy (&)[_OutSize])' : expects
3 arguments - 1 provided
1> c:\program files (x86)\microsoft visual studio
12.0\vc\include\xutility(2510) : see declaration of 'std::move'
Error C2893: Failed to specialize function template
'remove_reference<_Ty>::type &&std::move(_Ty &&) throw()'
1> With the following template arguments:
1> '_Ty=Victor::StateRef &'
Error C2227: left of '->Resume' must point to class/struct/union/generic
type
1> type is 'int'
Error C2780: '_OutTy *std::move(_InIt,_InIt,_OutTy (&)[_OutSize])' : expects
3 arguments - 1 provided
1> c:\program files (x86)\microsoft visual studio
12.0\vc\include\xutility(2510) : see declaration of 'std::move'
Error C2893:
Failed to specialize function template 'remove_reference<_Ty>::type
&&std::move(_Ty &&) throw()'
1> With the following template arguments:
1> '_Ty=Victor::StateRef &'
Error C2227: left of '->Initialize' must point to class/struct/union/generic
type
1> type is 'int'
Error C2440: 'return' : cannot convert from 'int' to 'Victor::StateRef &'
And This is the code that provides errors.
State.h
#pragma once
class State
{
public:
virtual void Initialize() = 0;
virtual void HandleInput() = 0;
virtual void Update() = 0;
virtual void Draw(float DeltaTime) = 0;
virtual void Pause()
{
}
virtual void Resume()
{
}
};
StateSystem.h
#pragma once
#include <memory>
#include <stack>
#include "State.h"
typedef std::unique_ptr <StateSystem> StateRef;
class StateSystem
{
public:
StateSystem()
{
}
~StateSystem()
{
}
void AddState(StateRef newStat, bool isReplacing = true);
void RemoveState();
void ProcessStateChanges();
StateRef &GetActiveState();
private:
std::stack<StateRef> _states;
StateRef _newState;
bool _isRemoving;
bool _isAdding;
bool _isReplacing;
};
StateSystem.cpp
#include "StateSystem.h"
void StateSystem::AddState(StateRef newState, bool isRepalcing)
{
this->_isAdding = true;
this->_isReplacing = isRepalcing;
this->_newState = std::move(newState);
}
void StateSystem::RemoveState()
{
this->_isRemoving = true;
}
void StateSystem::ProcessStateChanges()
{
if (this->_isRemoving && !this->_states.empty())
{
this->_states.pop();
if (!this->_states.empty())
{
this->_states.top()->Resume();
}
this->_isRemoving = false;
}
if (this->_isAdding)
{
if (!this->_states.empty())
{
if (this->_isReplacing)
{
this->_states.pop();
}
else
{
this->_states.top()->Pause();
}
}
this->_states.push(std::move(this->_newState));
this->_states.top()->Initialize();
this->_isAdding = false;
}
}
StateRef &StateSystem::GetActiveState()
{
return this->_states.top();
}
there's no StateSystem before typedef std::unique_ptr <StateSystem> StateRef; just add class StateSystem before it.
it says it cannot find the StateSystem class. you have to declare it first like this:
class StateSystem;
typedef std::unique_ptr <StateSystem> StateRef;
class StateSystem
{
//members
};
or put your typedef after the StateSystem definition like this:
class StateSystem
{
//members
};
typedef std::unique_ptr <StateSystem> StateRef;

c++ unordered_multimap insert hash

I'm going crazy over here. I have search google to find 1 single decent example where people use a unordered_map together with enum class and a hash function without any luck. Those i manage to find always end up saying "use map instead".
I'm trying to do the following:
Enum class facing is the direction my sprite is looking at.
Enum class Action is the action my sprite is doing.
Animation is a class that holds different animations which i will call later.
The container should look like this:
map
There can be more than 1 FACING in the map as key and there can be more than one ACTION in the pair.
Example:
map<LEFT, pair<ATTACK, attackAnimation>
map<LEFT, pair<IDLE, idleAnimation>
map<LEFTUP, pair<IDLE, idleAnimation>
This is an simplified everything
#include <iostream>
#include <unordered_map>
#include <string>
#include <memory>
template <typename T>
struct Hash
{
typedef typename std::underlying_type<T>::type underlyingType;
typedef typename std::hash<underlyingType>::result_type resultType;
resultType operator()(const T& arg) const
{
std::hash<underlyingType> hasher;
return hasher(static_cast<underlyingType>(arg));
}
};
class Animation
{
private:
std::string str;
public:
Animation(std::string _string)
{
this->str = _string;
}
std::string& GetString()
{
return this->str;
}
};
class Bullshit
{
public:
enum class Action
{
Attack,
Move
};
enum class Facing
{
Right,
Up,
Left
};
Bullshit()
{
}
std::unordered_multimap<Bullshit::Facing, std::pair<Bullshit::Action, std::unique_ptr<Animation>>,Hash<Bullshit::Facing>>& GetlistAnimation()
{
return this->listAnimation;
}
private:
std::unordered_multimap<Bullshit::Facing, std::pair<Bullshit::Action, std::unique_ptr<Animation>>,Hash<Bullshit::Facing>> listAnimation;
};
int main()
{
Bullshit bull;
auto myList = bull.GetlistAnimation();
std::unique_ptr<Animation> anim(new Animation("test"));
myList.insert(std::make_pair(Bullshit::Facing::Up, std::make_pair(Bullshit::Action::Attack, std::move(anim))));
std::cin.get();
return 0;
}
Error code:
error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=Animation
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=Animation
1> ]
1> This diagnostic occurred in the compiler generated function 'std::pair<_Ty1,_Ty2>::pair(const std::pair<_Ty1,_Ty2> &)'
1> with
1> [
1> _Ty1=Bullshit::Action,
1> _Ty2=std::unique_ptr<Animation>
1> ]
Here
auto myList = bull.GetlistAnimation();
the type deduced for myList is std::unordered_map<.....>, that is, it's not a reference. And the copy can't be created because the map contains unique_ptrs. What you meant is
auto& myList = bull.GetlistAnimation();
or in C++14,
decltype(auto) myList = bull.GetlistAnimation();
The problem has nothing to do with unordered_map or hash functions. It's the std::unique_ptr, which is uncopyable, and your GetlistAnimation attempts to copy it (indirectly).
How to correctly fix this depends on what you want to achieve.
A quick fix would be to use std::shared_ptr instead:
std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, std::shared_ptr<Animation>>,Hash<Bullshit::Facing>>& GetlistAnimation()
{
return this->listAnimation;
}
private:
std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, std::shared_ptr<Animation>>,Hash<Bullshit::Facing>> listAnimation;
[...]
std::shared_ptr<Animation> anim(new Animation("test"));
myList.insert(std::make_pair(Bullshit::Facing::Up, std::make_pair(Bullshit::Action::Attack, anim)));
(By the way, you should use std::make_shared and std::make_unique.)
A fix which may be quick and correct (again, depending on what you want to achieve) is to get rid of the pointer logic altogether and just use Animation directly:
std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, Animation>,Hash<Bullshit::Facing>>& GetlistAnimation()
{
return this->listAnimation;
}
private:
std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, Animation>,Hash<Bullshit::Facing>> listAnimation;
[...]
Animation anim("test");
myList.insert(std::make_pair(Bullshit::Facing::Up, std::make_pair(Bullshit::Action::Attack, anim)));

Failed to compile while the argument is lambda. [using hippomocks]

I wrote an unit test with hippomocks, but got error while compiling it.
The compiler is VS 2010.
How can I fix it ?
#include "hippomocks.h"
#include <functional>
using namespace HippoMocks;
struct A
{
virtual void f(std::function<void (int)> arg);
};
int main(void)
{
MockRepository mock;
A* aptr = mock.Mock<A>();
mock.ExpectCall(aptr, A::f); // error
return 0;
}
The output is :
main.cpp
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(323) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc
c:\users\cong\project\test\test\hippomocks.h(466) : error C2593: 'operator <<' i
s ambiguous
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\ostream(2
06): could be 'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Trai
ts>::operator <<(std::_Bool)'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
c:\users\cong\project\test\test\hippomocks.h(441): or 'std::ostrea
m &HippoMocks::operator <<(std::ostream &,const HippoMocks::NotPrintable &)'
while trying to match the argument list '(std::ostream, std::tr1::functi
on<_Fty>)'
with
[
_Fty=void (int)
]
c:\users\cong\project\test\test\hippomocks.h(463) : while compiling clas
s template member function 'void HippoMocks::printArg<T>::print(std::ostream &,T
,bool)'
with
[
T=std::tr1::function<void (int)>
]
c:\users\cong\project\test\test\hippomocks.h(614) : see reference to cla
ss template instantiation 'HippoMocks::printArg<T>' being compiled
with
[
T=std::tr1::function<void (int)>
]
Enhancing #dascandy's comment here is how his method can look like. Place it after including hippomocks.h:
template<>
struct printArg<std::function<void (int)> >
{
static inline void print(std::ostream &os, std::function<void (int)> arg, bool withComma)
{
if (withComma)
{
os << ",";
}
if (arg)
{
os << "true";
}
else
{
os << "false";
}
}
};
Note that I didn't test this very example but rather took our solution and adapted the type to the original post's example. I'd be happy to know whether this works for you.

Stack Data Structure as a Template: Main method do not identify methods in stack

Please have a look at the following code,
Stack.h
template <typename T>
class Stack
{
public:
Stack(int number)
{
maxSize = number;
top = -1;
stackData = new T*[maxSize];
}
~Stack()
{
delete [] stackData;
}
int count()
{
}
bool isEmpty()
{
if(top==-1)
{
return true;
}
else
{
return false;
}
}
bool isFull()
{
if(top== (maxSize-1))
{
return true;
}
else
{
return false;
}
}
*T pop()
{
if(!isEmpty())
{
return stackData[top--]; // Remove Item From Stack
}
}
*T peek()
{
T *peekData = &stackData[top];
return peekData;
}
void push(T *pushValue)
{
if(!isFull())
{
stackData[++top] = pushValue;
}
}
private:
int maxSize;
T ** stackData;
int top;
};
Main.cpp
#include <iostream>
#include "Stack.h"
#include <iostream>
using namespace std;
int main()
{
int i = 0;
Stack<double> doubleStack(5);
double doubleValue = 1.1;
cout << "pushing elements into the stack" << endl;
while(i<5)
{
doubleStack.push();
}
system("pause");
return 0;
}
When I run this code, I get the following error.
1>------ Build started: Project: CourseWork2, Configuration: Debug Win32 ------
1> Main.cpp
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(48): error C2146: syntax error : missing ';' before identifier 'pop'
1> c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(74) : see reference to class template instantiation 'Stack<T>' being compiled
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(48): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(49): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(54): warning C4183: 'pop': missing return type; assumed to be a member function returning 'int'
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(56): error C2146: syntax error : missing ';' before identifier 'peek'
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(56): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(57): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(60): warning C4183: 'peek': missing return type; assumed to be a member function returning 'int'
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(48): error C2146: syntax error : missing ';' before identifier 'pop'
1> c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\main.cpp(11) : see reference to class template instantiation 'Stack<T>' being compiled
1> with
1> [
1> T=double
1> ]
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(48): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(49): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(49): warning C4183: 'pop': missing return type; assumed to be a member function returning 'int'
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(56): error C2146: syntax error : missing ';' before identifier 'peek'
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(56): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(57): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\stack.h(57): warning C4183: 'peek': missing return type; assumed to be a member function returning 'int'
1>c:\users\yohan\documents\visual studio 2010\projects\coursework2\coursework2\main.cpp(18): error C2660: 'Stack<T>::push' : function does not take 0 arguments
1> with
1> [
1> T=double
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Intellelisense is not identifying any method except isFull(), count() and isEmpty(). I can't code the rest because of this!
Why is this? Please help!
You put * at wrong place in function syntax:
Update:
*T pop()
*T peek()
To:
T* pop()
T* peek()
You put the asterisk in the wrong spot. It should be:
T *pop() {
//implementation
}
and
T *peek() {
//implementation
}

What causes C4250 (class inherits member via dominance) when using boost serialization with a virtual base class?

The meaning of the VC++ compiler warning C4250 'class1' : inherits 'class2::member' via dominance is clear to me. (But see here for an explanation.)
I have currently the problem that I get this warning when serializing a class hierarchy that has an abstract base class with boost::serialization (1.44.0).
Please note that my classes do not form any kind of diamond-like inheritance hierarchy that could cause this warning, but the warning is caused by the instantiation of boost::detail::is_virtual_base_of_impl<...> when serializing instances of derived classes. (Which seems to be using is_virtual_base_of from Boost.TypeTraits.)
Here is a minimal code sample to reproduce the warning on Visual Studio 2005. Note that the code should be dropped as-is into one cpp-file and it should compile.
Note also the two points in the code that I have marked by comments that trigger the warning. If BOOST_CLASS_EXPORTis not used then the warning is not triggerd, but more interestingly the warning is also not triggered, if the derived class does not use virtual inheritance! (So maybe I do not understand C4250 after all.)
// -- std includes --
#include <iostream>
#include <sstream>
#include <string>
// -- boost serialization --
#define BOOST_SERIALIZATION_DYN_LINK
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
// Base with serialization support
struct Base
{
virtual ~Base() {};
virtual void DoStuff() const {
std::cout << "Base#[" << static_cast<const void*>(this) << "]::DoStuff() called\n";
}
template<class Archive> // serialization support!
void serialize(Archive & ar, const unsigned int file_version) { /*empty*/ }
};
// (The only) Specific class with ser. support
struct Concrete2 : virtual/*!C4250!*/ public Base
{
virtual void DoStuff() const {
std::cout << "Concrete2#[" << static_cast<const void*>(this) << "]::DoStuff() called\n";
}
template<class Archive> // serialization support!
void serialize(Archive & ar, const unsigned int ver) {
ar & boost::serialization::base_object<Base>(*this);
// This is just a test - no members neccessary
std::cout << "Concrete2::serialize!" << typeid(ar).name() << "\n";
}
};
// Without guid export -> *no* C4250, even *with* virtual inheritance
// (however, can't be serialized via base class pointer anymore)
BOOST_CLASS_EXPORT(Concrete2);
BOOST_CLASS_TRACKING(Concrete2, boost::serialization::track_never);
int main() {
using namespace std;
Concrete2 obj1;
obj1.DoStuff();
// The following test code is not neccessary to generate the warning ...
// (but is neccessary to show if base-pointer serialization works at runtime)
Base* ref1 = &obj1;
ostringstream out_buf;
boost::archive::text_oarchive out_archive(out_buf);
out_archive << ref1;
const string buf = out_buf.str();
cout << "Serialized obj:\n~~~~\n";
cout << buf;
cout << "\n~~~~~\n";
std::istringstream in_buf(buf);
boost::archive::text_iarchive in_archive(in_buf);
// Concrete2 obj2;
Base* ref2;
in_archive >> ref2;
if(ref2)
ref2->DoStuff();
delete ref2;
}
And here is the compiler warning (ugh!):
1>...\boost_library-1_44_0\boost\type_traits\is_virtual_base_of.hpp(61) : warning C4250: 'boost::detail::is_virtual_base_of_impl<Base,Derived,tag>::X' : inherits 'Concrete2::Concrete2::DoStuff' via dominance
1> with
1> [
1> Base=type,
1> Derived=Concrete2,
1> tag=boost::mpl::bool_<true>
1> ]
1> ...\boostserializewarningtest\vbc.cpp(27) : see declaration of 'Concrete2::DoStuff'
...
1> ...\boost_library-1_44_0\boost\mpl\eval_if.hpp(40) : see reference to class template instantiation 'boost::mpl::if_<T1,T2,T3>' being compiled
1> with
1> [
1> T1=boost::is_virtual_base_of<type,Concrete2>,
1> T2=boost::mpl::identity<boost::serialization::void_cast_detail::void_caster_virtual_base<Concrete2,type>>,
1> T3=boost::mpl::identity<boost::serialization::void_cast_detail::void_caster_primitive<Concrete2,type>>
1> ]
1> ...\boost_library-1_44_0\boost\serialization\void_cast.hpp(279) : see reference to class template instantiation 'boost::mpl::eval_if<C,F1,F2>' being compiled
1> with
1> [
1> C=boost::is_virtual_base_of<type,Concrete2>,
1> F1=boost::mpl::identity<boost::serialization::void_cast_detail::void_caster_virtual_base<Concrete2,type>>,
1> F2=boost::mpl::identity<boost::serialization::void_cast_detail::void_caster_primitive<Concrete2,type>>
1> ]
1> ...\boost_library-1_44_0\boost\serialization\base_object.hpp(68) : see reference to function template instantiation 'const boost::serialization::void_cast_detail::void_caster &boost::serialization::void_cast_register<Derived,Base>(const Derived *,const Base *)' being compiled
1> with
1> [
1> Derived=Concrete2,
1> Base=type
1> ]
...
1> ...\boost_library-1_44_0\boost\serialization\export.hpp(128) : while compiling class template member function 'void boost::archive::detail::`anonymous-namespace'::guid_initializer<T>::export_guid(boost::mpl::false_) const'
1> with
1> [
1> T=Concrete2
1> ]
1> ...\boostserializewarningtest\vbc.cpp(40) : see reference to class template instantiation 'boost::archive::detail::`anonymous-namespace'::guid_initializer<T>' being compiled
1> with
1> [
1> T=Concrete2
1> ]
The reason is in fact the is_virtual_base_of check from boost type traits. This check-construct will generate warning C4250 if the check is successful, as can be seen by this example:
...
struct base {
virtual void mf() { };
};
struct derived_normal : public base {
virtual void mf() { };
};
struct derived_virt : virtual public base {
virtual void mf() { };
};
int main() {
using namespace std;
cout << "boost::is_virtual_base_of<base, derived_normal>::value reports: ";
// The following line DOES NOT cause C4250
cout << boost::is_virtual_base_of<base, derived_normal>::value << endl;
cout << "boost::is_virtual_base_of<base, derived_virt> reports: ";
// The following line causes C4250:
cout << boost::is_virtual_base_of<base, derived_virt>::value << endl;
...
FWIW, the usage of this type-traits tool in boost serialization goes like this:
macro BOOST_EXPORT_CLASS ->
macro BOOST_CLASS_EXPORT_IMPLEMENT ->
struct guid_initializer (in export.hpp) ->
(...) void_cast.hpp / void_cast_register -> is_virtual_base_of is used here
As far as I can tell the warning is completely harmless in this case and can be prevented by wrapping the header in:
#pragma warning( push )
#pragma warning( disable : 4250 ) // C4250 - 'class1' : inherits 'class2::member' via dominance
#include ...
#pragma warning( pop ) // C4250