我最近开始使用右值参考,我遇到了一个我不明白为什么他们按照他们的方式工作的情况.
我正在尝试确定一个类型是否可以拥有begin并end调用它.下面的代码给出了预期的结果,如果我改变foo把它通过值或const引用参数,但我不知道为什么使用右值引用,我想知道是否有人能告诉我为什么当它不工作.
#include <vector>
#include <type_traits>
#include <iostream>
template<class Container>
auto begin(Container &&c) -> decltype(c.begin()) { return c.begin(); }
template<class Container>
auto end(Container &&c) -> decltype(c.end()) { return c.end(); }
template<class T, size_t size>
T *begin(T (&array)[size]) { return (&array[0]); }
template<class T, size_t size>
T *end(T (&array)[size]) { return (&array[0] + size); }
template <typename T>
struct has_begin_end
{
typedef char true_type;
typedef char false_type[2];
template <typename U> static true_type& test(decltype(begin(*((U*)0))) *b = …Run Code Online (Sandbox Code Playgroud) 我想知道是否存在某种形式的类型擦除来处理具有相同名称和参数但返回不同值的方法,如下面的示例(begin和end)中所示.我不打算在任何地方实际使用它,我只是想知道它是否可能,如果是的话,它将如何完成.
我所知道的唯一一种类型的擦除形式是指向一个纯虚拟concept类的指针,该虚拟类指向一个model<T>转发对底层调用的调用T.但是,这要求所有T的包含具有完全相同签名的方法,而在我的示例中,返回类型不同.据我所知,类似于虚拟模板功能的东西需要做我要问的事情,但我可能会遗漏一些东西.
class Iterable
{
//how would this be defined?
}
int main(int argc, char *argv[])
{
vector<int> v = {1, 2, 3, 4, 5};
set<string> s = {"foo", "bar", "baz"};
Iterable iterable;
if(argc == 2) iterable = v;
else iterable = s;
for(auto val : it)
{
cout << val << ' ';
}
}
Run Code Online (Sandbox Code Playgroud)