英文:
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<T>
.
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 <limits>
#include <iostream>
// Some user-defined numeric type,
// for which I'd like to specialize std::numeric_limits<T>.
struct S {};
namespace std
{
// My specialization, for brevity providing only max()
template <>
struct numeric_limits<S>
{
static /*constexpr*/ S max()
{
std::cout << "got called" << '\n';
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<S>::max(); // Prints 'got called'
std::numeric_limits<const S>::max(); // Prints 'got called'
std::numeric_limits<volatile S>::max(); // Prints 'got called'
std::numeric_limits<const volatile S>::max(); // Prints 'got called'
}
答案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-qualifiedT
is equal to the value of the same member ofnumeric_limits<T>
.
The proposed (and implemented) resolution was:
-
Add to the synopsis of the
<limits>
header, immediately below the declaration of the primary template, the following:template <class T> class numeric_limits<const T>; template <class T> class numeric_limits<volatile T>; template <class T> class numeric_limits<const volatile T>;
These are for example implemented in gcc as such:
template<typename _Tp> struct numeric_limits<const _Tp> : public numeric_limits<_Tp> { }; template<typename _Tp> struct numeric_limits<volatile _Tp> : public numeric_limits<_Tp> { }; template<typename _Tp> struct numeric_limits<const volatile _Tp> : public numeric_limits<_Tp> { };
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 <iostream>
// STD
template<class T>
struct foo {
inline static constexpr bool is_S = false;
};
template <class T> struct foo<const T> : foo<T> {};
template <class T> struct foo<volatile T> : foo<T> {};
template <class T> struct foo<const volatile T> : foo<T> {};
Now add a type, S
, and a specialization for foo<S>
only:
// User-defined type and foo specialization:
struct S {};
template<>
struct foo<S> {
inline static constexpr bool is_S = true;
};
and foo<const volatile S>
will pick the specialization:
int main() {
std::cout << foo<const volatile S>::is_S << '\n'; // prints 1
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论