【问题标题】:Is it legal in C++ to specialize std::minus for user-defined types?在 C++ 中为用户定义的类型专门化 std::minus 是否合法?
【发布时间】:2021-05-24 12:32:40
【问题描述】:

标准库是否允许用户将函数对象(如 std::plusstd::minus)专门用于自定义类型?

如果我的第一个问题的答案是肯定的,是否允许用户更改呼叫运营商的声明?例如,由于 C++14 std::minus::operator() 声明如下:

constexpr T operator()( const T& lhs, const T& rhs ) const;

更改此运算符使其不再是 constexpr 或返回 double 而不是 T 是否合法?

namespace std
{
    template <> 
    struct minus<MyArrayType>
    {
        double operator ()(const MyArrayType& x, const MyArrayType& y) const
        {
            return l2_norm(x - y);
        }
    };
}   // std

【问题讨论】:

  • 你不应该覆盖operator -吗?
  • @user253751 假设,该类型的运算符 - 已经定义,但我想改变它的行为,以便它可以以不同的方式使用。
  • 那么你应该使用不同的函子而不是 std::minus。做一个mentalmushroom::l2_norm_minus
  • @user253751 嗯,有道理,但想象一下,对于我的特殊需求,专门化 std::minus 会更方便。此外,我有一个普遍的好奇心:)
  • 更有趣的问题是:WHY?哪个算法使用这个模板?这个算法/​​模板是你的吗?

标签: c++


【解决方案1】:

extending namespace std 的规则说:

只有当声明依赖于至少一种程序定义的类型并且特化满足原始模板的所有要求时,才允许将任何标准库类模板的模板特化添加到命名空间std ,除非此类专业化被禁止。

(强调我的)

因此,在您的情况下,为程序定义类型 MyArrayType 添加特化会起作用。

但是,operator() 成员的返回类型必须MyArrayType,而不是double。此外,成员operator()必须constexpr

违反其中任何一个都意味着专业化不满足主模板的要求。

【讨论】:

  • 谢谢,您如何理解“原始模板的要求”这句话?它们在哪里被描述?
  • 我不确定“原始模板的要求”一词的确切位置。但是,您可以看到原始(主)模板的要求是返回类型和参数类型必须匹配。此外,主模板必须可在 constexpr 上下文中调用(来自 C++14)。另一个例子是成员 operator() 必须是 const 限定的。
  • “意义”也可能是“要求”arithmetic.operations#plus 的一部分。但是其他一些模板有明确的要求/先决条件,这似乎不是这里的情况......
猜你喜欢
  • 2014-08-13
  • 2019-03-16
  • 2018-06-10
  • 2019-04-18
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多