【问题标题】:Inheritance and template operator overloading继承和模板运算符重载
【发布时间】:2016-06-15 21:35:29
【问题描述】:

继承和模板运算符重载

我不明白为什么A<int> 中的运算符会掩盖base 中的运算符。 毕竟它有不同的签名。

#include <iostream>

struct base {
  template <typename U>
  void operator()(U&& x) { std::cout << "base" << std::endl; }
};

template <typename T>
struct A: public base { };

template <>
struct A<int>: public base {
  void operator()() { std::cout << "A<int>" << std::endl; } // line 1
};

int main()
{
  A<double>()(1);
  A<int>()(1); // line 2
  A<int>()();  // line 3
}

如果存在第 1 行,则第 2 行不会编译。

如果删除第 1 行(很明显),则第 3 行不会编译。

如果我将运算符模板从基础复制到 A,一切正常。

我预计输出是:

base
base
A<int>

【问题讨论】:

  • 这叫做名字隐藏。参见例如stackoverflow.com/questions/1628768/…
  • 您可以通过在 A 类中插入 using base::operator(); 来解决此问题。请注意,可访问性取决于您插入 using 声明的位置,并且您可以更改与父级声明相关的可访问性(例如通过将 using 放入 public 部分使受保护的功能公开)。
  • 请注意,您不能以这种方式“取消隐藏”单个函数 - 要么全部重载,要么不重载(例外:父级中只有一个具有给定名称的函数...)。

标签: c++ templates inheritance operator-overloading


【解决方案1】:

派生类中的操作符声明隐藏了基类中的名称。
解决这个问题,只需using declaration

template <>
struct A<int>: public base {
    using base::operator();
    void operator()() { std::cout << "A<int>" << std::endl; }
};

它们都会编译。

【讨论】:

  • 谢谢,这行得通。 using declaration 的重点是防止多重继承问题吗?如果标准规定除非存在using declaration,否则会使用第一个列出的父类中的函数吗?
  • 在评论中回答了这个问题:stackoverflow.com/a/1629074/2640636 谢谢@Alan Stokes
猜你喜欢
  • 1970-01-01
  • 2011-12-05
  • 2012-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多