gpt4 book ai didi

c++ - 在 C++11 中使用 auto 和 decltype

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

我正在尝试学习当前接受的 c++11 功能,但我在使用 auto 和 decltype 时遇到了问题。作为学习练习,我正在使用一些通用函数扩展 std 类列表。

template<class _Ty, class _Ax = allocator<_Ty>>
class FList : public std::list<_Ty, _Ax>
{
public:
void iter(const function<void (_Ty)>& f)
{
for_each(begin(), end(), f);
}

auto map(const function<float (_Ty)>& f) -> FList<float>*
{
auto temp = new FList<float>();

for (auto i = begin(); i != end(); i++)
temp->push_back(f(*i));

return temp;
}
};

auto *ints = new FList<int>();
ints->push_back(2);
ints->iter([](int i) { cout << i; });

auto *floats = ints->map([](int i) { return (float)i; });
floats->iter([](float i) { cout << i; });

对于成员映射,我希望返回类型是通用的,具体取决于传递的函数返回的内容。所以对于返回类型,我可以做这样的事情。

auto map(const function<float (_Ty)>& f) -> FList<decltype(f(_Ty))>*

这也需要去掉函数模板中的float类型。

auto map(const function<auto (_Ty)>& f) -> FList<decltype(f(_Ty))>*

我可以使用模板类,但这会使实例的使用更加冗长,因为我必须指定返回类型。

template<class T> FList<T>* map(const function<T (_Ty)>& f)

总而言之,我想弄清楚如何在不使用模板类的情况下定义 map ,并且在它返回的类型中仍然具有通用性。

最佳答案

不鼓励从 std::list 或其他 std:: 容器派生。

将您的操作编写为自由函数,以便它们可以通过迭代器在任何标准容器上工作。

你的意思是“不使用模板函数定义 map ”吗?

您应该能够使用 std::functionresult_type 成员类型来获取它返回的类型。

您也没有必要指定该函数作为 std::function 传递。您可以将其作为任何类型打开,并让编译器将所有内容连接起来。对于运行时多态性,您只需要 std::function

使用 new 创建原始堆分配对象并通过指针返回它们是 1992 年的事! :)

您的 iter 函数本质上与 range-based for loop 相同.

但是除此之外......你是说这样的意思吗?

template <class TFunc>
auto map(const TFunc &f) -> FList<decltype(f(_Ty()))>*
{
auto temp = new FList<decltype(f(_Ty()))>();

for (auto i = begin(); i != end(); i++)
temp->push_back(f(*i));

return temp;
}

这将匹配任何可调用的对象,并将使用 decltype 确定函数的返回类型。

请注意,它要求 _Ty 是默认可构造的。您可以通过制造一个实例来解决这个问题:

template <class T>
T make_instance();

不需要实现,因为没有生成调用它的代码,所以链接器没有什么可提示的(感谢 dribeas 指出了这一点!)

所以现在的代码变成了:

FList<decltype(f(make_instance<_Ty>()))>*

或者,从字面上看,通过引用 _Ty 的实例调用函数 f 将得到的任何类型的列表。

作为接受的免费奖励,查找右值引用 - 这些意味着您可以写:

std::list<C> make_list_somehow()
{
std::list<C> result;
// blah...
return result;
}

然后这样调用它:

std::list<C> l(make_list_somehow());

因为 std::list 将有一个“移动构造函数”(就像一个复制构造函数,但是当参数是临时的时被选择,就像这里一样),它可以窃取返回值的内容,即做与最优交换。所以没有复制整个列表。 (这就是为什么 C++0x 会让天真编写的现有代码运行得更快——许多流行但丑陋的性能技巧将变得过时)。

并且您可以通过使用 unique_ptr 为您自己的任何现有类免费获得相同类型的东西,而无需编写正确的移动构造函数。

std::unique_ptr<MyThing> myThing(make_my_thing_somehow());

关于c++ - 在 C++11 中使用 auto 和 decltype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1094046/

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