正确的模板习语直觉

问题描述

我正在尝试更深入地理解 C++ 模板元编程。我不明白的是模板的真正含义。具体来说,对于具有静态成员的模板化类来说,习语是什么。以下面的例子:

template <class T>
class Matrix {
  private:
    
  public:
    static constexpr Matrix<T> Identity(int,int);
    static constexpr Matrix<T> Zero(int,int);
    static constexpr Matrix<T> Null = Matrix();

    typdef value_type;

    Matrix();
    Matrix(int,int);
}

Matrix 的静态成员函数显然构造了典型的矩阵。我的想法是,思考文本(习语)Matrix<T>::Identity 的方式应该是类的身份矩阵 value_type = T

TL;DR

重申一下,我相信上面的模板会生成一个 set 类,其中包含各自“类型”的静态成员 Matrix<T>::Identity。这与某些 Matrix::Identity<T>() 的其他直观语义相比,后者是所有矩阵的 T 类型的标识。哪个是正确的?

解决方法

没有任何其他条件,Matrix<T>::identityMatrix::identity<T> 没有什么不同。它只是看起来像 someFunction<T>。所以没有任何成语。

但另一方面,很多实际问题会让你选择更好的。

  1. Matrix::identity<T> 是什么?如果 Matrix<T> 表示元素类型为 T 的矩阵类,那么 Matrix 本身是什么?它是一个类模板,所以它不能有任何没有实例化的成员。在这种情况下,您应该定义一个单独的类(例如,名为 MatrixUtility),并使用 MatrixUtility::identity<T>。听起来很吵吧?

  2. 但是,Matrix::identity(或MatrixUtility::identity)呢?通常可以在上下文中推导出类型 T。例如:

Matrix<int> a = MatrixUtility::identity(3,3); // T=int is required in this context.
auto lambda = [](Matrix<double>){};
lambda(MatrixUtility::identity(2,2)); // T=double is required in this context.

所以有一个棘手的方法来实现它,通过 operator T() 的自动推导:

struct Helper{
    template<typename T>
    operator Matrix<T>(){
        // construct and return
    };
    int w,h;
};

struct MatrixUtility{
    Helper identity(int w,int h){
        return Helper{ w,h };
    }
};

在这种情况下,MatrixUtility 实际上是必要的。

  1. 尽管如此,您还需要 MatrixUtility::identity<T>,因为有时需要单态:
template<typename T>
void foo(Matrix<T>);

auto a = MatrixUtility::identity(3,3); // unexpected,a has type of Helper.
auto b = MatrixUtility::identity<int>(3,3); // ok.
foo(MatrixUtility::identity(3,3)); // ill-formed,T is not deducible.
foo(MatrixUtility::identity<int>(3,3)); // well-formed.

最后,您选择的实现应该取决于您真正需要的东西。你需要一个多态性,然后选择MatrixUtility::identity;您需要最简化,然后选择Matrix<T>::identity;而不是遵守固定的习惯用法。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...