【问题标题】:Class Template non-type member access in sub-class子类中的类模板非类型成员访问
【发布时间】:2020-08-23 15:02:39
【问题描述】:

我有一个Matrix 类模板,如下所示:

using matrix_size_t = unsigned int;
using matrix_data_t = double;

template <matrix_size_t row, matrix_size_t col>
class Matrix
{
protected:
    matrix_data_t m_matrix[row][col];

//more code irrelevant to the question...
}

我还有一个子类模板SquareMatrix,看起来像这样:

template <matrix_size_t size>
class SquareMatrix :public Matrix<size, size>
{
public:
    matrix_data_t trace()
    {
        matrix_data_t trace{ 0 };
        for (matrix_size_t j{ 0 }; j < size; ++j)
        {
            trace += m_matrix[j][j]; //C3861 error in MVS: m_matrix identifier not found
        }
        return trace;
    }
};

问题是:我无法从子类访问成员 m_matrix

当我用Matrix&lt;size,size&gt;::m_matrix 替换m_matrix 时,子类代码有效:

template <matrix_size_t size>
class SquareMatrix :public Matrix<size, size>
{
public:
    matrix_data_t trace()
    {
        matrix_data_t trace{ 0 };
        for (matrix_size_t j{ 0 }; j < size; ++j)
        {
            trace += Matrix<size, size>::m_matrix[j][j]; //this works
        }
        return trace;
    }
};

我不知道这样做是否正确。请帮助我了解发生了什么!

【问题讨论】:

  • 请写trace += this-&gt;m_matrix[j][j];。继承成员的自动解析在模板类中不起作用。您必须提供m_matrix 确实来自何处的明确提示。 (您在第三个 sn-p 中使用的范围运算符是另一种选择。)
  • 明白了!但是,作用域运算符的用法正确吗?还是会在未来某个时候导致一些 UD 行为?
  • 但是,作用域运算符的用法正确吗?或者它会在未来的某个时候导致一些 UD 行为? 我真的不相信这会在未来打破。除了模板,如果你有一个类和一个派生类,其中派生类重载了一个成员,你如何访问基类的成员(同名)? ;-)

标签: c++ templates generic-programming template-classes class-template


【解决方案1】:

我不知道这样做是否正确。

是的。您也可以改用this-&gt;m_matrix

m_matrix是一个非依赖的名字,不会在依赖的基类Matrix&lt;size, size&gt;中查找,它依赖于模板参数size。使m_matrix依赖为Matrix&lt;size, size&gt;::m_matrixthis-&gt;m_matrix,则在实例化时会查找名称,届时将知道必须探索的基类特化。

【讨论】:

  • 那么,使用任何一个都会导致相同的结果,对吧?还是我还缺少其他东西...例如性能损失或某些未来的 UD 行为...?
  • @AbhishekAUdupa 类似性能损失 不太可能。我很确定每个严肃的 C++ 编译器在这两种情况下都应该发出完全相同的代码。 (但您可以在 CompilerExplorer 中尝试一下。)
  • @AbishekAUdupa 因为这两种方式都适用于成员变量。和函数,我习惯于使用this-&gt; 作为变量。和函数,但类型的范围(this-&gt; 不适用)。这还提供了一些“视觉效果”,因为那时事物更容易区分。 (如果派生模板类中的某些内容已重载,但必须解决基类的重载成员(如我在其他评论中提到的那样),那么当然,您必须再次回退到范围。)
  • 现在我明白了。
猜你喜欢
  • 2015-04-20
  • 1970-01-01
  • 2017-11-27
  • 2020-03-28
  • 2021-07-25
  • 2012-01-24
  • 2010-12-08
  • 2020-11-29
  • 2019-04-12
相关资源
最近更新 更多