gpt4 book ai didi

c++ - 一般开始,加上 decltype 考虑本地 using-declaration

转载 作者:可可西里 更新时间:2023-11-01 15:24:59 26 4
gpt4 key购买 nike

C++0x 的 ranged-for 循环有一个处理数组的特殊异常(exception)(FDIS §6.5.4),并且有两个函数,std::begin 和 end,它们被重载以处理数组或选择 begin/结束方法。这使我相信可以编写一个接受通用序列的函数来匹配范围 for 循环的行为:

template<class C>
void f(C &c) {
using std::begin;
using std::end;
do_something_with(begin(c), end(c));
}

如果 C 的命名空间中有一个“更具体”的开始/结束,它将通过 ADL 选择,否则代码“默认”为 std::begin/end。

但是,ranged-for 有这个特殊的异常(exception)是有原因的。如果在命名空间中传递一个类型的数组,该数组具有采用指针的语义不同的开始/结束,则不会选择 std::begin/end 的数组形式:

namespace ns {
struct A {};
void begin(A*); // Does something completely different from std::begin.
}

void f_A() { // Imagine above f() called with an array of ns::A objects.
ns::A c[42];
using std::begin;
begin(c); // Selects ns::begin, not array form of std::begin!
}

为了避免这种情况,是否有比编写我自己的开始/结束包装器(在内部使用 ADL)并显式调用它们而不是 std::begin 或 ADLized begin 更好的解决方案?

namespace my {
template<class T>
auto begin(T &c) // Also overload on T const &c, as std::begin does.
-> decltype(...) // See below.
{
using std::begin;
return begin(c);
}

template<class T, int N>
T* begin(T (&c)[N]) {
return c;
}
}
// my::end omitted, but it is analogous to my::begin.

template<class C>
void f(C &c) {
do_something_with(my::begin(c), my::end(c));
}

但是,如上省略号所示,我什至不知道如何写my::begin!对于该 decltype,我如何选择将通过本地 using 声明和 ADL 选择的类型?

最佳答案

我在使用元组时遇到过同样的情况:

template<typename Tuple>
auto f(Tuple&& tuple)
-> /* ??? */
{
using std::get;
return get<Idx>(tuple);
}

同时接受 std::tupleboost::tuple , 并接受左值和右值而不是 template<typename... Types> auto f(std::tuple<Types...>& tuple) -> /* ??? */ .

这个特殊情况是用一个特征类解决的,它实际上是由标准提供的:std::tuple_element .与特征类一样,想法是 tuple是一个协议(protocol),任何想要遵守它的东西都会提供一个特化,例如tuple_element .所以就我而言,解决方案已经存在。

在您的情况下,如果您正在编写一个库,我建议您编写(并记录)这样一个特征类。在应用程序代码或其他情况下,我不太确定。

关于c++ - 一般开始,加上 decltype 考虑本地 using-declaration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6045054/

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