C++ 检查容器中是否存在函数的概念 class 和隐式推导规则
C++ Concepts for checking if a function exists in a container class and implicit deduction rules
我正在尝试弄清楚如何做一些在概念和模板类型方面对我来说似乎很棘手的事情,例如 std::vector。
我正在尝试应用类似于我在 T 上使用 std::movable 的编译时间约束,但在 C 上使用 PushBackMovable。它适用于函数声明尾部的要求,但我想保持一致并将我的约束放在模板参数中。我尝试用 "PushBackMovable C" 替换 "class C",但这并没有那么失败,但更接近我想要的。
我正在尝试在模板化模板参数中使用模板类型。
2a.有什么方法可以只声明 C 并在它的签名中使用其中的模板参数
功能?例如,我可以删除 "T" 和 "Alloc",然后使用“_T”和“_Alloc”骑行吗?它似乎
我无法访问这些参数。我想保存一些代码 space.
2b.他们是删除运算符第一个参数上 C 上的空 <> 的方法吗?
2c.如果我只有 PushBackMovable,编译器可以根据需要推断出 C 的模板类型,
但随后呕吐。我是否缺少隐式确定模板的任何技巧
参数,特别是 "C" 实例?最好只说 "C".
- 他们检查方法是否存在的方法是否比下面的更简单?
这是我针对这两种情况的示例代码:
#include <vector>
#include <type_traits>
#include <algorithm>
template<typename T, typename Alloc, template<typename _T=T, typename _Alloc=Alloc> class C >
concept PushBackMovable = std::is_same_v<decltype(std::declval<C<T,Alloc> >().push_back(std::move(T{}))),void> &&
std::is_same_v<decltype(std::declval<C<T,Alloc> >().push_back(T{})),void>;
template<std::movable T, typename Alloc, template<typename _T=T, typename _Alloc=Alloc> class C >
void operator+=( C<>& lhs, T rhs ) requires PushBackMovable<T, Alloc, C>
{
lhs.push_back( std::forward<T>( rhs ) );
}
int main() {
std::vector<int> ints;
int a = 5;
ints += 1;
ints += a;
std::copy(std::begin(ints), std::end(ints), std::ostream_iterator<int>(std::cout, " "));
}
感谢您的帮助。
通过使用模板-模板参数,您已经将函数限制在遵循标准库模式的容器中,但也限制在 class 恰好具有两个类型模板参数的模板中。这是一个强约束,在实践中通常没有用。也就是说,我建议您改为对由类型模板参数表示的具体类型进行操作,并让概念验证您想要强加的任何要求。
此外,不要使用 decltype
和 std::declval
以及 std::is_same
来检查表达式的有效性。 Concepts 有专门的语法用于此目的,就是将这个表达式放在大括号中。
一个解决方案,将您要验证的内容合并到一个概念中,可能如下所示:
#include <concepts>
#include <utility>
#include <type_traits>
template <typename C, typename T>
concept PushBackMovable = requires (C c, T t) {
{ c.push_back(t) } -> std::same_as<void>;
{ c.push_back(std::move(t)) } -> std::same_as<void>;
};
template <typename T, PushBackMovable<std::remove_reference_t<T>> C>
void operator+=(C& lhs, T&& rhs)
{
lhs.push_back(std::forward<T>(rhs));
}
我正在尝试弄清楚如何做一些在概念和模板类型方面对我来说似乎很棘手的事情,例如 std::vector。
我正在尝试应用类似于我在 T 上使用 std::movable 的编译时间约束,但在 C 上使用 PushBackMovable。它适用于函数声明尾部的要求,但我想保持一致并将我的约束放在模板参数中。我尝试用 "PushBackMovable C" 替换 "class C",但这并没有那么失败,但更接近我想要的。
我正在尝试在模板化模板参数中使用模板类型。
2a.有什么方法可以只声明 C 并在它的签名中使用其中的模板参数 功能?例如,我可以删除 "T" 和 "Alloc",然后使用“_T”和“_Alloc”骑行吗?它似乎 我无法访问这些参数。我想保存一些代码 space.
2b.他们是删除运算符第一个参数上 C 上的空 <> 的方法吗?
2c.如果我只有 PushBackMovable,编译器可以根据需要推断出 C 的模板类型, 但随后呕吐。我是否缺少隐式确定模板的任何技巧 参数,特别是 "C" 实例?最好只说 "C".- 他们检查方法是否存在的方法是否比下面的更简单?
这是我针对这两种情况的示例代码:
#include <vector>
#include <type_traits>
#include <algorithm>
template<typename T, typename Alloc, template<typename _T=T, typename _Alloc=Alloc> class C >
concept PushBackMovable = std::is_same_v<decltype(std::declval<C<T,Alloc> >().push_back(std::move(T{}))),void> &&
std::is_same_v<decltype(std::declval<C<T,Alloc> >().push_back(T{})),void>;
template<std::movable T, typename Alloc, template<typename _T=T, typename _Alloc=Alloc> class C >
void operator+=( C<>& lhs, T rhs ) requires PushBackMovable<T, Alloc, C>
{
lhs.push_back( std::forward<T>( rhs ) );
}
int main() {
std::vector<int> ints;
int a = 5;
ints += 1;
ints += a;
std::copy(std::begin(ints), std::end(ints), std::ostream_iterator<int>(std::cout, " "));
}
感谢您的帮助。
通过使用模板-模板参数,您已经将函数限制在遵循标准库模式的容器中,但也限制在 class 恰好具有两个类型模板参数的模板中。这是一个强约束,在实践中通常没有用。也就是说,我建议您改为对由类型模板参数表示的具体类型进行操作,并让概念验证您想要强加的任何要求。
此外,不要使用 decltype
和 std::declval
以及 std::is_same
来检查表达式的有效性。 Concepts 有专门的语法用于此目的,就是将这个表达式放在大括号中。
一个解决方案,将您要验证的内容合并到一个概念中,可能如下所示:
#include <concepts>
#include <utility>
#include <type_traits>
template <typename C, typename T>
concept PushBackMovable = requires (C c, T t) {
{ c.push_back(t) } -> std::same_as<void>;
{ c.push_back(std::move(t)) } -> std::same_as<void>;
};
template <typename T, PushBackMovable<std::remove_reference_t<T>> C>
void operator+=(C& lhs, T&& rhs)
{
lhs.push_back(std::forward<T>(rhs));
}