我需要像“使用Base :: *;”这样的东西

时间:2011-08-07 07:20:54

标签: c++ metaprogramming

如果我的基类具有函数func(int)并且我的派生类具有函数func(double),则派生的func(double)隐藏base::func(int)。我可以使用using将基本版本带入derive的重载列表中:

struct base
{
   void func(int);
};

struct derived : base
{
   using base::func;
   void func(double);
}
好的,太好了。但是如果我不确定base是否有func()怎么办?即因为我正在进行模板元编程,我实际上并不确定base是什么,但我想将其功能提升到同一级别 - 如果它们存在的话。即将上述示例更改为:

struct base_with
{
   void func(int);
};
struct base_without
{
};

template <typename Base>
struct derived : Base
{
   using Base::func;  // if Base has a func(), I want to bring it in

   void func(double);
}

derived<base_with> testwith; // compiles
derived<base_without> testwithout;  // fails :-(

我需要using_if boost::enable_if。似乎不可能......

提前致谢。

2 个答案:

答案 0 :(得分:1)

由于您愿意将using语句放入派生类中,因此我假设您知道您可能有兴趣引入哪些成员。您可以使用{{{ 1}}:

boost::enable_if

对所有打印声明表示抱歉。现在,如果你尝试

struct base_with
{
    void func(int) { cout << "func(int)" << endl; }
};

struct base_without { };

// Custom traits, by default assume func() isn't present
template <class T> struct has_func : public boost::false_type { };

template<> struct has_func<base_with> : public boost::true_type { };

// Again, if nothing else is known, assume absence of func(int)
template <typename Base, class UseFunc = void> struct derived : Base
{
    derived() { cout << "ctor: derived without" << endl; }
    void func(double) { cout << "func(double)" << endl; }
};

// Derived with func(int)
template <typename Base> struct derived<Base, typename boost::enable_if< has_func<Base> >::type> : Base
{
    using Base::func; 
    derived() { cout << "ctor: derived with" << endl; }
    void func(double) { cout << "func(double)" << endl; }
};

你应该看到

  

ctor:派生于   ctor:派生而没有   FUNC(INT)
  FUNC(双)
  FUNC(双)
  func(double)

显然,如果您尝试测试多个功能,这将会获得 monstrous 。如果我正在进行这样的mixin风格编程,我可能宁愿使用具有不同名称的函数来实现不同的功能,这样它们就不会互相隐藏 - 那么公共继承将是所有需要的。无论如何有趣的问题。

答案 1 :(得分:0)

我想我需要做一些像

这样的事情
struct dummy_func
{
private:
   struct dumb_type {};

// interesting: does this need to be public?
public:
   // use a type that no one can see, so func is never chosen by ADT
   // and vararg just for paranoia
   void func(dumb_type, dumb_type, dumb_type,...) { };
};

...
template <typename T>
struct has_func
{
   enum { value = /* insert metaprogramming magic that checks for T::func */ }
};

template <typename Base>
struct derived : Base
{
   using enable_if<has_func<Base>, Base, dummy_func>::type::func;
   ...
};

哎呀。当然这不起作用,因为dummy_func不是derived的基础。在我的情况下,我可以在必要时从它衍生出来。但仍然不能令人满意。