Is it guaranteed that a specialization of std::numeric_limits<T> for user-defined numeric type S works for cv-qualified S out of the box?

huangapple go评论58阅读模式
英文:

Is it guaranteed that a specialization of std::numeric_limits<T> for user-defined numeric type S works for cv-qualified S out of the box?

问题

以下是您要翻译的内容:

我有一个用户定义的数值类型 S,我为其专门化了 std::numeric_limits<T>

尽管我只专门化了 S,但我的自定义 max() 也用于带有常量限定符的 S,至少在最近版本的 gcc 和 MSVC 中是这样。

这是否有保证可以正常工作,还是我依赖于实现细节?

英文:

I have a user-defined numeric type S for which I specialized std::numeric_limits&lt;T&gt;.

Although I specialized for S only, my custom max() is also used for cv-qualified S, at least with recent versions of gcc and MSVC.

Is this guaranteed to work, or am I relying on an implementation detail here?

#include &lt;limits&gt;
#include &lt;iostream&gt;

// Some user-defined numeric type,
// for which I&#39;d like to specialize std::numeric_limits&lt;T&gt;.
struct S {};

namespace std
{
    // My specialization, for brevity providing only max()
    template &lt;&gt;
    struct numeric_limits&lt;S&gt;
    {
        static /*constexpr*/ S max()
        {
            std::cout &lt;&lt; &quot;got called&quot; &lt;&lt; &#39;\n&#39;;
            return S();
        }
    };
}

int main()
{
    // Although I specialize for S only, my custom max() is also used for cv-qualified S.
    // Is this guaranteed, or am I relying on an implementation detail here? 
    std::numeric_limits&lt;S&gt;::max();                // Prints &#39;got called&#39;
    std::numeric_limits&lt;const S&gt;::max();          // Prints &#39;got called&#39;
    std::numeric_limits&lt;volatile S&gt;::max();       // Prints &#39;got called&#39;
    std::numeric_limits&lt;const volatile S&gt;::max(); // Prints &#39;got called&#39;
}

答案1

得分: 16

The provided text appears to be a technical discussion related to C++ programming, specifically concerning the standard library and template specializations for numeric_limits and foo types. It includes code examples and references to specific C++ proposals and implementations.

Is there anything specific you would like me to do with this text?

英文:

Yes, it's guaranteed since LWG559 which dealt with this specifically by requiring that

  • The value of each member of a numeric_limits specialization on a cv-qualified T is equal to the value of the same member of numeric_limits&lt;T&gt;.

The proposed (and implemented) resolution was:

  • Add to the synopsis of the &lt;limits&gt; header, immediately below the declaration of the primary template, the following:

    template &lt;class T&gt; class numeric_limits&lt;const T&gt;;
    template &lt;class T&gt; class numeric_limits&lt;volatile T&gt;;
    template &lt;class T&gt; class numeric_limits&lt;const volatile T&gt;;
    

    These are for example implemented in gcc as such:

    template&lt;typename _Tp&gt;
      struct numeric_limits&lt;const _Tp&gt;
      : public numeric_limits&lt;_Tp&gt; { };
    
    template&lt;typename _Tp&gt;
      struct numeric_limits&lt;volatile _Tp&gt;
      : public numeric_limits&lt;_Tp&gt; { };
    
    template&lt;typename _Tp&gt;
      struct numeric_limits&lt;const volatile _Tp&gt;
      : public numeric_limits&lt;_Tp&gt; { };
    

The LWG issue also has an informal note at the bottom:

  • [ Portland: Martin will clarify that user-defined types get cv-specializations automatically. ]

You can see that the addition to the standard works as intended by implementing a similar type, here called foo:

#include &lt;iostream&gt;

// STD
template&lt;class T&gt;
struct foo {
    inline static constexpr bool is_S = false;
};

template &lt;class T&gt; struct foo&lt;const T&gt; : foo&lt;T&gt; {};
template &lt;class T&gt; struct foo&lt;volatile T&gt; : foo&lt;T&gt; {};
template &lt;class T&gt; struct foo&lt;const volatile T&gt; : foo&lt;T&gt; {};

Now add a type, S, and a specialization for foo&lt;S&gt; only:

// User-defined type and foo specialization:

struct S {};

template&lt;&gt;
struct foo&lt;S&gt; {
    inline static constexpr bool is_S = true;
};

and foo&lt;const volatile S&gt; will pick the specialization:

int main() {
    std::cout &lt;&lt; foo&lt;const volatile S&gt;::is_S &lt;&lt; &#39;\n&#39;; // prints 1
}

Demo

huangapple
  • 本文由 发表于 2023年6月9日 02:49:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76434884.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定