gpt4 book ai didi

c++ - 如何在C++概念中定义emplace_back和其他可变参数模板函数?

转载 作者:行者123 更新时间:2023-12-02 10:20:14 25 4
gpt4 key购买 nike

我正在尝试为允许push_back / emplace_back的标准库容器定义C++概念:

template <class ContainerType>
concept PushBackContainer = requires(ContainerType a)
{
requires SequenceContainer<ContainerType>;
{ a.push_back(typename ContainerType::const_reference& v) };
{ a.push_back(typename ContainerType::value_type&& v) };
// How do you define a variable templated function:
{ template< class... Args > a.emplace_back(Args&&... args) };
}

我的问题是如何使用可变参数模板参数定义emplace_back?我正在使用Visual Studio 2019,但是如果不支持此功能,我会对正确的语法感兴趣。

最佳答案

大概值得做的最好的事情就是a.emplace_back();

您的push_back要求也没有正确的语法。我想你要:

template <class ContainerType>
concept PushBackContainer = requires(
ContainerType& a,
typename ContainerType::value_type const& cv,
typename ContainerType::value_type& v)
{
requires SequenceContainer<ContainerType>;
a.push_back(cv);
a.push_back(std::move(v));
a.emplace_back();
};

需求不检查功能签名;他们检查表达式的有效性(无需实例化更多不必要的模板)。如果我们有一个像这样的类(class):
class StrangeContainer {
public:
using value_type = std::string;
using const_reference = const value_type&;
private:
struct ValueHolder {
ValueHolder(const std::string& s) : value(s) {}
ValueHolder(std::string&& s) : value(std::move(s)) {}
std::string value;
};
public:
void push_back(ValueHolder);

template <typename ... Args>
void emplace_back(Args&&...);
};

然后忽略 SequenceContainer要求, PushBackContainer<StrangeContainer>将为true,并且还将满足标准自身与 push_back相关的要求。尽管它具有一些令人惊讶的效果,例如 push_back("")格式不正确,但它满足了技术要求。

因此,对于 push_back,我们实际上只是检查是否可以使用 const左值和非 const右值来调用它。 (该标准实际上还要求可以使用非 const左值和 const左值来调用它,这些情况与使用 const左值来调用时具有相同的行为。)

(如果您确实想测试确切的 push_back签名,则可以尝试 static_cast<void (ContainerType::*)(typename ContainerType::value_type&&)>(&ContainerType::push_back);-但这是不建议的,因为 namespace std中的成员函数不需要具有完全与所描述的签名相同,只能使用相同的参数进行调用,就像按照说明声明。)

此外,标准容器类模板对其 push_backemplace_back函数没有任何限制。带有 push_back的模板的每个实例化都声明两个重载,无论类型是可复制的还是可移动的。如果不是,那么实际上调用或以其他方式odd使用 push_back函数将是一个错误,但是出于require表达式和SFINAE上下文的目的而“存在”。同样, emplace_back成员模板被声明为接受任意数量的具有任何类型和值类别的参数,无论它们是否可用作 value_type构造函数参数。

因此,我们需要测试的内容是:容器是否具有带有基本普通可变参数函数声明的 emplace_back:可以用任意数量的参数调用 emplace_back,每个参数具有任何可能的类型,并且每个参数可以是左值还是右值?我认为没有任何方法可以在C++中使用require-表达式,SFINAE技巧或其他方式真正回答这一问题。因此,我将对某种 emplace_back的存在进行一个简单的测试,并且该测试可能会尽可能地简单:零参数。

您可能会觉得更奇特,还可以测试其他一些情况: emplace_back是否接受不同数量的参数,最多达到固定的最大值?它接受左值和右值参数吗?它接受伪 struct类型的参数吗?虚拟的 struct类型不是MoveConstructible吗? constvolatileconst volatile类型?所有上述所有可能的组合?但是,由于您将永远无法涵盖所有​​情况,因此与添加检查所需的工作量,复杂性和维护相比,这样的每个部分增强实际上能带来多少值(value)?

关于c++ - 如何在C++概念中定义emplace_back和其他可变参数模板函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60491342/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com