【问题标题】:Templated implicit type conversion operator模板化隐式类型转换运算符
【发布时间】:2018-05-03 23:20:18
【问题描述】:

我已经实现了

template<int M, int N, typename T=double>
class matrix{
    // ...
}

并且希望能够在需要 T 的地方使用 matrix&lt;1,1,T&gt;

我应该如何做到这一点?下面的工作吗?

template<typename T>
operator T(matrix<1, 1, T> mat) {
    return mat(0,0);
}

(甚至期望遇到matrix&lt;1,1,T&gt; 的原因是某些矩阵表达式具有这种类型。例如,将matrix&lt;1,3&gt;matrix&lt;3,1&gt; 相乘得到matrix&lt;1,1&gt;。)

【问题讨论】:

    标签: c++ c++11 templates casting


    【解决方案1】:

    您列出的代码将无法编译,因为您实际上是在尝试在 T 的定义之外实现 T 构造函数;或者如果它是一个基本类型,或者一个数组,它就更没有意义了。

    您可以做的是在您的矩阵类中实现一个转换运算符 - 通过将其添加到通用模板或将 matrix 专门用于 M=1 和 N=1。

    第一个选项如下所示:

    template<int M, int N, typename T=double>
    class matrix{
        // ...
        operator T() const {
            static_assert(M == 1 and N==1, 
                "Attempting to treat a matrix with multiple cells as a scalar");
            // code to return the single matrix element
        }
    }
    

    第二个:

    template<int M, int N, typename T=double>
    class matrix{
        // ...
    }
    
    
    template<typename T=double>
    class matrix<1, 1, T>{
        // ... some code duplication here with the main template; or maybe
        // actually have different implementation banking on the fact that
        // it's really just a scalar.
    
        operator T() const {
            // code to return the single matrix element
        }
    }
    

    但坦率地说,我不认为我会推荐这些选项中的任何一个。我可能会执行以下操作之一:

    • 采用 T 的改变函数,以便它可以“自然地”采用 1x1 矩阵(例如通过模板)
    • 采用 T 的 Alter 函数可以“自然地”采用 任何 矩阵。许多标量工作对矩阵进行了有趣的推广。
    • 明确说明转换,可能编写一个template &lt;typename T&gt; T as_scalar(const matrix&lt;1,1,T&gt; m) 函数。

    【讨论】:

    • 有无数的函数,包括标准库中的许多函数,它们采用double,但不是matrix&lt;1, 1, double&gt;。我觉得这个是隐式转换的好用处。
    • 每当我尝试专门化模板时,我都会得到很多重复。 static_assert 方法是否会与模板特化完全相同,因为 static_assert 在 SFINAE 中被视为替换失败?
    • operator std::enable_if_t&lt;M==1 &amp;&amp; N==1,T&gt;() const {...} 怎么样?
    • @Museful:关于 static_assert - 我认为这行不通,因为只有声明而不是定义被认为是 w.r.t。 SFINAE;见this answerenable_if_t 听起来不错。
    【解决方案2】:

    把它放在类定义中:

    template<int Md=M, int Nd=N, typename = std::enable_if_t<Md==1 && Nd==1>>
    operator T() const {
        return (*this)(0,0);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      相关资源
      最近更新 更多