std::size 的用户重载?
User overloads of std::size?
在 std
命名空间中添加 size
的重载是否符合标准?我有一个无法更改的 class,但我希望 std::size
也能为它工作;在通用设置中。
来自cppreference:
It is undefined behavior to add declarations or definitions to namespace std or to any namespace nested within std, with a few exceptions noted below
在同一页的更下方(直到 C++20):
It is allowed to add template specializations for any standard library function template to the namespace std only if the declaration depends on at least one program-defined type and the specialization satisfies all requirements for the original template, except where such specializations are prohibited.
但是从 C++20 开始:
It is undefined behavior to declare a full specialization of any standard library function template.
但是,由于 ADL,您无需为 std::size
提供专业化。这有效:
#include <array>
#include <iostream>
#include <cstddef>
template <typename T>
size_t get_size_example(const T& t) {
using std::size;
return size(t);
}
namespace Foo {
struct bar {};
size_t size(const bar& b){ return 42;}
}
int main(){
std::array<int,5> x;
Foo::bar b;
std::cout << size(b) << "\n";
std::cout << size(x) << "\n";
std::cout << get_size_example(b) << "\n";
std::cout << get_size_example(x) << "\n";
}
并打印:
42
5
42
5
在 std
命名空间中添加 size
的重载是否符合标准?我有一个无法更改的 class,但我希望 std::size
也能为它工作;在通用设置中。
来自cppreference:
It is undefined behavior to add declarations or definitions to namespace std or to any namespace nested within std, with a few exceptions noted below
在同一页的更下方(直到 C++20):
It is allowed to add template specializations for any standard library function template to the namespace std only if the declaration depends on at least one program-defined type and the specialization satisfies all requirements for the original template, except where such specializations are prohibited.
但是从 C++20 开始:
It is undefined behavior to declare a full specialization of any standard library function template.
但是,由于 ADL,您无需为 std::size
提供专业化。这有效:
#include <array>
#include <iostream>
#include <cstddef>
template <typename T>
size_t get_size_example(const T& t) {
using std::size;
return size(t);
}
namespace Foo {
struct bar {};
size_t size(const bar& b){ return 42;}
}
int main(){
std::array<int,5> x;
Foo::bar b;
std::cout << size(b) << "\n";
std::cout << size(x) << "\n";
std::cout << get_size_example(b) << "\n";
std::cout << get_size_example(x) << "\n";
}
并打印:
42
5
42
5