是否有一种方法,从类定义中推导出成员函数的auto
返回类型,并将其与using
声明一起使用?例如,我想要:
#include <vector>
class Foo {
public:
Foo() = default;
auto begin() const { return v_.begin(); }
auto end() const { return v_.end(); }
private:
std::vector<int> v_;
public:
using iterator = decltype(std::declval<Foo>().begin());
};
这当然会给编译器带来错误
error: use of 'auto Foo::begin() const' before deduction of 'auto'
15 | using iterator = decltype(std::declval<Foo>().begin());
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~
因为假定auto
直到类型Foo
完成之后才被推导。然而,原则上,编译器在using iterator = ...
点上确实有足够的信息来推断类型。
可以用template<typename=void> using iterator = ...
替换using iterator = ...
,但这意味着必须使用Foo::iterator<>
而不是Foo::iterator
类型,这对Container不起作用。
3条答案
按热度按时间nmpmafwu1#
您可以使用与用于推导方法的返回类型相同的表达式,即
declval(v_.begin())
:或尾随返回类型:
PS:不要写一个什么都不做的构造函数。如果你想声明它,那么就把它设为
Foo() = default;
。jc3wubiy2#
在这里我们被
If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression, the program is ill-formed.
规则所束缚类成员的返回类型的推导直到类本身可以完成才完成。除了463035818_is_not_a_number所写的,在某些情况下,我们可能会交错演绎(并将实现与接口分离)。对最简单的类没有意义,但对CRTP很有用。
反过来,
FooProps
可能是一个mix-in,然后容器的定义转到trait类。yiytaume3#
然而,原则上,编译器在使用iterator = ...时似乎有足够的信息。来推断类型。
你可能会这么想,但事后提供额外的信息可以改变答案:
通过添加
begin
的非const
重载,我们将iterator
的类型从std::vector<int>::const_iterator
更改为std::vector<int>::iterator
。相反,写一些不需要
Foo
完整的东西,例如: