对非模板类型使用通用引用?
Using universal references with non template types?
我正在为向量构建一个简单的管道运算符,用户可以像这样使用它(伪代码):
auto x = std::vector{1,2,3} | push_back(10)
| push_back(100)
;
现在我尝试像这样定义管道运算符:
template <typename T>
constexpr inline auto& operator| (std::vector<T>&& vec, std::invocable<std::vector<T>> auto&& func);
但是现在vec只对右值(因为vec本身的类型没有推导)!但我也希望它绑定到左值。我该怎么做?
一个丑陋但实用的解决方案是为我的管道操作员创建另一个重载,但使用 std::vector<int>&
。然而,这是不可扩展的,( 2 ^ n 重载 n 个参数!),我相信这就是创建通用引用的原因。
在这种情况下如何使用通用引用?
当然,您可以使用转发引用。
template <typename T> inline constexpr bool is_vector = false;
template <typename ...P> inline constexpr bool is_vector<std::vector<P...>> = true;
template <typename T> requires is_vector<std::remove_cvref_t<T>>
constexpr auto &operator|(T &&vec, std::invocable<T> auto &&func);
另外,请记住,通常应在与其参数之一相同的命名空间中创建运算符,以便 ADL 可以找到它们。但是你不能碰namespace std
...
此外,我不喜欢重载运算符的想法,其中两个参数都不是 you 创建的 class。除非您的用户必须通过 using namespace ...;
.
明确选择加入这些运营商
我正在为向量构建一个简单的管道运算符,用户可以像这样使用它(伪代码):
auto x = std::vector{1,2,3} | push_back(10)
| push_back(100)
;
现在我尝试像这样定义管道运算符:
template <typename T>
constexpr inline auto& operator| (std::vector<T>&& vec, std::invocable<std::vector<T>> auto&& func);
但是现在vec只对右值(因为vec本身的类型没有推导)!但我也希望它绑定到左值。我该怎么做?
一个丑陋但实用的解决方案是为我的管道操作员创建另一个重载,但使用 std::vector<int>&
。然而,这是不可扩展的,( 2 ^ n 重载 n 个参数!),我相信这就是创建通用引用的原因。
在这种情况下如何使用通用引用?
当然,您可以使用转发引用。
template <typename T> inline constexpr bool is_vector = false;
template <typename ...P> inline constexpr bool is_vector<std::vector<P...>> = true;
template <typename T> requires is_vector<std::remove_cvref_t<T>>
constexpr auto &operator|(T &&vec, std::invocable<T> auto &&func);
另外,请记住,通常应在与其参数之一相同的命名空间中创建运算符,以便 ADL 可以找到它们。但是你不能碰namespace std
...
此外,我不喜欢重载运算符的想法,其中两个参数都不是 you 创建的 class。除非您的用户必须通过 using namespace ...;
.