导入基类成员函数重载集到派生类中,仅在基类提供任何内容时使用

时间:2019-03-27 17:37:49

标签: c++ using-declaration

如果我将成员函数f添加到派生类,这将隐藏基类f的整个重载集

struct B2{
  int f(int);
  int f(float);
};
struct D: B2{
  int f(std::string);
};
D b;
b.f(42); // fails to compile because int B2::f(int) is not available.

对此的标准解决方法是使用声明

struct D: B2 {
  int f(std::string);
  using B2::f;
};

在我的情况下,B是模板参数:

template <typename B>
struct D: B {
  int f(std::string);
  using B::f;
};

还有一个困难,即B可能有或没有f方法,并且基类中缺少f会导致编译器错误。


struct B1 {
};

template <typename B>
struct D: B {
  int f(std::string);
  using B::f;
};

void test() {
  D<B1> b; // error: no members matching 'B1::f' in 'struct B1'
}

类似于别名声明的模板显然不能用于using声明:

#include <string>
#include <type_traits>

struct B1 {
};

template <typename B>
struct D: B {
  int f(std::string);
  template <typename = typename std::enable_if_t<std::is_same_v<B2, B>>>
  using B::f;
};

void test() {
  D<B1> b;
}

这导致

<source>:15:10: error: expected '=' before '::' token
   using B::f;
          ^~
<source>:15:12: error: 'f' in namespace '::' does not name a type
    using B::f;

所以,我的问题是,基于编译时已知的东西(在代码编写时未知),使using声明出现/消失的推荐方法是什么? (即我正在考虑使用sfinae / std :: enable_if / if constexpr)。

PS:

我正在考虑在f中使用可变参数化模板方法D,该方法通常会重定向到基类f,并专门介绍我想添加的一个选项。这也许比using声明更好吗?

0 个答案:

没有答案