我想在编译时确定是否可以从没有dynamic_cast <>的指针转换为指向Derived的指针.这可能使用模板和元编程吗?这与确定Base是否是Derived的虚拟基类不完全相同,因为Base可能是Derived虚拟基类的超类.
谢谢Tim更新:我觉得这个方法很好:
#include <iostream>
using namespace std;
class Foo
{
};
class Bar : public Foo
{
};
class Baz : public virtual Foo
{
};
class Autre : public virtual Bar
{
};
typedef char Small;
class Big { char dummy[2]; };
template<typename B, typename D>
struct is_static_castable
{
const B* foo;
char bar[1];
static Small test(char(*)[sizeof(static_cast<const D*>(foo)) == sizeof(const D*)]);
static Big test(...);
enum { value = (sizeof(test(&bar)) == sizeof(Small)) };
};
int main()
{
cout << "Foo -> Bar: " << is_static_castable<Foo, Bar>::value << "\n";
cout << "Foo -> Baz: " << is_static_castable<Foo, Baz>::value << "\n";
cout << "Foo -> Autre: " << is_static_castable<Foo, Autre>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)
但它不适用于gcc:
multi-fun.cpp: In instantiation of ‘is_static_castable<Foo, Baz>’:
multi-fun.cpp:38: instantiated from here
multi-fun.cpp:29: error: cannot convert from base ‘Foo’ to derived type ‘Baz’ via virtual base ‘Foo’
multi-fun.cpp:29: error: array bound is not an integer constant
multi-fun.cpp: In instantiation of ‘is_static_castable<Foo, Autre>’:
multi-fun.cpp:39: instantiated from here
multi-fun.cpp:29: error: cannot convert from base ‘Foo’ to derived type ‘Autre’ via virtual base ‘Bar’
multi-fun.cpp:29: error: array bound is not an integer constant
Run Code Online (Sandbox Code Playgroud)
我对使用sizeof()技巧可以做些什么感到困惑?
mef*_*fiX 11
我有同样的问题,一次.不幸的是,我不太确定虚拟问题.但是:升压有一个名为类is_base_of
(见这里),这将使你做不便.如下
BOOST_STATIC_ASSERT((boost::is_base_of<Foo, Bar>::value));
Run Code Online (Sandbox Code Playgroud)
此外,还有一类is_virtual_base_of
在Boost的type_traits
,也许这就是你要找的内容.
这是一个解决方案,用于重定向编译器以执行某些操作,具体取决于该类是否是另一个的子类.
class A
{};
class B : virtual public A
{};
class C : public A
{};
// Default template which will resolve for
// all classes
template
< typename T
, typename Enable = void
>
struct FooTraits
{
static void foo(){
std::cout << "normal" << std::endl;
}
};
// Specialized template which will resolve
// for all sub classes of A
template
< typename T
>
struct FooTraits
< T
, typename boost::enable_if
< boost::is_virtual_base_of< A, T>
>::type
>
{
static void foo(){
std::cout << "virtual base of A" << std::endl;
}
};
int main(int argc, const char * argv[] ){
FooTraits<C>::foo(); // prints "normal"
FooTraits<B>::foo(); // prints "virtual base of A"
}
Run Code Online (Sandbox Code Playgroud)
如果你想知道增压是如何做到的.如果您有类Base和类Derived,那么以下内容成立.
struct X : Derived, virtual Base
{
X();
X(const X&);
X& operator=(const X&);
~X()throw();
};
struct Y : Derived
{
Y();
Y(const Y&);
Y& operator=(const Y&);
~Y()throw();
};
bool is_virtual_base_of = (sizeof(X)==sizeof(Y)));
Run Code Online (Sandbox Code Playgroud)
这是使用具有多重继承性的虚拟继承的技巧.来自同一虚拟基础的多重继承不会导致虚拟基类的重复,因此您可以使用sizeof对其进行测试.