如何在不使用c ++ 0x标准的情况下实现自动关键字功能?
for(std::deque<std::pair<int, int> >::iterator it = points.begin();
it != points.end(); ++it)
{
...
}
也许这样的课程:
class AUTO
{
public:
template <typename T1>
AUTO(T1);
template <typename T2>
operator T2();
};
有了这样的用法:
for(AUTO it = points.begin(); it != points.end(); ++it)
{
...
}
但是,T1和T2是不同的。 如何将有关T1的信息移至运营商T2()? 真的有可能吗?
答案 0 :(得分:12)
如果可以轻松实现库扩展,则不需要语言扩展。有关自动提案的详细信息,请参阅N1607。
然而,article上的Boost.Foreach(您想要的那种)宏可能有助于理解与此类实施相关的问题。
什么是BOOST_FOREACH?
在C ++中,编写一个迭代的循环 一个序列是乏味的。我们可以 使用迭代器,需要一个 相当数量的锅炉板, 或者我们可以使用std :: for_each() 算法并将我们的循环体移动到 谓词,不需要少 锅炉板,迫使我们搬家 远离它将被使用的逻辑。 相比之下,其他一些语言, 像Perl一样,提供专用 “foreach”构造自动化 这个流程。 BOOST_FOREACH就是 这样的C ++构造。它迭代 为我们排序,让我们摆脱困境 必须直接处理迭代器 或写谓词。
BOOST_FOREACH是专为 易用性和效率。它没有 动态分配,没有虚拟 函数调用或调用 函数指针,不进行调用 这是不透明的 编译器的优化器。这导致了 接近最优的代码生成;该 BOOST_FOREACH的表现是 通常在百分之几的范围内 等效的手动编码循环。和 虽然BOOST_FOREACH是一个宏,但它 是一个非常乖巧的人。它 只评估一次参数, 导致没有令人讨厌的惊喜。
答案 1 :(得分:10)
有一个BOOST_AUTO宏或多或少地执行auto关键字...但是,看一下它的实现会告诉你找到一种使用C ++ 0x的方法要好得多:&gt;
答案 2 :(得分:3)
您可以使用这些宏以符合标准的方式解决此问题。
#define DEF_DED(D, E) any_base const & D = make_any_concrete((E))
#define DED(D, E) get_t(D, true ? ded_ty() : get_idt((E)))
template<typename T> struct id {
typedef T type;
};
template<typename T>
id<T> get_idt(T t) { return id<T>(); }
struct any_base { };
template<typename D>
struct any_concrete : any_base {
any_concrete(D d):d(d) {}
mutable D d;
};
template<typename T>
any_concrete<T> make_any_concrete(T x) { return any_concrete<T>(x); }
struct ded_ty {
template<typename T>
operator id<T>() { return id<T>(); }
};
template<typename T>
T &get_t(any_base const &b, id<T>) { return static_cast<any_concrete<T> const&>(b).d; }
所以你的for循环成为
for(DEF_DED(it, points.begin());
DED(it, points.begin()) != points.end();
++DED(it, points.begin()))
{
...
}
Eric Niebler将信用转到Conditional Love: FOREACH Redux。不确定这是否真的值得:)
答案 3 :(得分:2)
更直接的问题是从推导类型获取信息到数据成员声明。
class AUTO
{
public:
template <typename T1>
AUTO(T1);
T1 state; // eg deque<...>::iterator - need this!
};
显然不会发生这种情况,因为必须在调用函数之前分配AUTO
对象。
鉴于typeof
或decltype
,它并不是那么难。
#define AUTO( name, initializer ) typeof( initializer ) name = initializer
当然,这有很多限制。并typeof
不标准。有了多个编译器支持,这可能是这些Boost工具的基础。