用于检查容器类中是否存在函数和隐式演绎规则的C++概念 [英] C++ Concepts for checking if a function exists in a container class and implicit deduction rules

查看:18
本文介绍了用于检查容器类中是否存在函数和隐式演绎规则的C++概念的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解决一些在概念和模板类型(如std::VECTOR)方面对我来说似乎很棘手的事情。

  1. 我正在尝试应用编译时间约束,类似于我在T上使用std::move的方式,但在C上使用PushBackMoovable时。它与函数Decl末尾的Requires一起工作,但我希望保持一致,并将我的约束放在模板args中。我试着用"PushBackMoovable C"替换"C类",但失败得不是很严重,但更接近我想要的。

  2. 我正在尝试使用模板模板参数中的模板类型。
    2A。有没有办法只声明C,并在它的签名内使用模板参数 功能呢?例如,我可以去掉"T"和"Alalc",而使用"_T"和"_Allc"吗?似乎 我不能访问这些参数。我想节省一些代码空间。
    2B。它们是否可以删除运算符第一个参数上C上的空<;>?
    2C。如果我刚刚有了PushBackMoable,编译器可以在Requires上推导出C的模板类型, 但后来就开始呕吐了。我是否遗漏了他们隐式确定模板的技巧 参数,特别是在"C"实例上?如果只说"C"就好了。

  3. 检查方法是否比下面的方法更容易?

以下是我针对这两种情况的示例代码:

#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, " "));
}

感谢您的帮助。

推荐答案

通过使用模板-模板参数,您已经将函数约束到遵循标准库模式的容器,但也约束到恰好有两个类型模板参数的类模板。这是一个很强的约束,在实践中通常毫无用处。也就是说,我建议您改为操作由类型模板参数表示的具体类型,并让概念验证您想要施加的任何要求。

此外,不要使用decltypeWITHstd::declvalWITHstd::is_same来检查表达式的有效性。概念有专门的语法用于此目的,它只是将该表达式放在大括号中。

一个解决方案是将您要验证的内容合并到一个概念中,可能如下所示:

#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));
}

DEMO

这篇关于用于检查容器类中是否存在函数和隐式演绎规则的C++概念的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆