是否存在不需要Boost的「for each」宏如BOOST_FOREACH
的實現?BOOST_FOREACH沒有提升?
0
A
回答
3
我做了一個。
它應該與GCC和MSVC中的C++ 11 r值引用一起工作,但我沒有很好地測試它,所以如果有任何錯誤,請讓我知道。
編輯:我添加了對字符串的支持。
#include <iterator>
#include <utility>
#define foreach(v, r) \
if (fe_detail::any const &fe_r_ = \
fe_detail::make_range(r)) { } else \
if (fe_detail::any const &fe_b_ = \
fe_detail::begin(fe_r_, ((void)0, 1) ? NULL : fe_detail::twrap(r))) { } else \
if (fe_detail::equal(\
fe_b_, \
fe_detail::end(fe_r_, ((void)0, 1) ? NULL : fe_detail::twrap(r)), \
((void)0, 1) ? NULL : fe_detail::twrap(r))) { } else \
for (bool fe_c_ = false; \
!fe_c_ && !fe_detail::equal(\
fe_b_, \
fe_detail::end(fe_r_, ((void)0, 1) ? NULL : fe_detail::twrap(r)), \
((void)0, 1) ? NULL : fe_detail::twrap(r)); \
fe_detail::advance(fe_b_, 1, ((void)0, 1) ? NULL : fe_detail::twrap(r))) \
for (v = (fe_detail::move(*fe_detail::iter(fe_b_, ((void)0, 1) ? NULL : fe_detail::twrap(r)))); \
fe_c_ = !fe_c_;)
namespace fe_detail
{
// Container traits
template<class C, class It> struct CT
{
typedef It It;
static It begin(C &c) { return c.begin(); }
static It end(C &c) { return c.end(); }
};
// Range traits
template<class R> struct RT : public CT<R, typename R::iterator> { };
template<class R> struct RT<R const> : public CT<R const, typename R::const_iterator> { };
template<class R> struct RT<R &> : public RT<R> { };
template<class T, bool B = T::value> struct enable_if;
template<class T> struct enable_if<T, true> { typedef T type; };
template<class T> struct is_char { static bool const value = false; };
template<class T> struct is_char<T const> : public is_char<T> { };
template<class T> struct is_char<T volatile> : public is_char<T> { };
template<> struct is_char<char> { static bool const value = true; };
template<> struct is_char<wchar_t> { static bool const value = true; };
template<class Ch> struct RT<Ch *> : enable_if<is_char<Ch> >
{
typedef Ch *It;
static It begin(It a) { return &a[0]; }
static It end(It a) { return &a[std::char_traits<Ch>::length(a)]; }
};
template<class R, size_t N> struct RT<R[N]>
{
typedef R *It;
static It begin(It a) { return &a[0]; }
static It end(It a) { return &a[N - (((void)0, is_char<R>::value) ? 1 : 0)]; }
};
template<class It> struct RT<std::pair<It, It> >
{
typedef It It;
static It begin(std::pair<It, It> const a) { return a.first; }
static It end(std::pair<It, It> const a) { return a.second; }
};
struct any { operator bool() const { return false; } };
template<class T> struct type_wrap { type_wrap(bool = false) { } };
template<class T> class wrap : public any
{ wrap &operator =(wrap const &); public: mutable T v; wrap(T v) : any(), v(v) { } };
template<class T> class wrap<T const> : public any
{ wrap &operator =(wrap const &); public: T const v; wrap(T const v) : any(), v(v) { } };
template<class T, size_t N> class wrap<T[N]> : public any
{ wrap &operator =(wrap const &); public: T (&v)[N]; wrap(T (&v)[N]) : any(), v(v) { } };
template<class T> class wrap<T const &> : public wrap<T const>
{ wrap &operator =(wrap const &); public: wrap(T const &v) : wrap<T const>(v) { } };
template<class T, size_t N> wrap<T[N]> make_range(T (&r)[N]) { return r; }
template<class T, size_t N> type_wrap<T[N]> twrap(T (&r)[N]) { throw 0; }
template<class It> type_wrap<std::pair<It, It> > twrap(std::pair<It, It> const &p) { throw 0; }
#if defined(_MSC_VER) && _MSC_VER >= 1600 || defined(__RVALUE_REFERENCE) || defined(__GXX_EXPERIMENTAL_CXX0X__)
template<class R> struct RT<R &&> : public RT<R> { };
template<class T> class wrap<T &&> : public wrap<T> { public: wrap(T &&v) : wrap<T>(std::move(v)) { } };
template<class R> wrap<R &&> make_range(R &&r) { return wrap<R &&>(std::forward<R>(r)); }
template<class R> type_wrap<R> twrap(R &&) { throw 0; }
using std::move;
#else
template<class R> wrap<R> make_range(R &r) { return r; }
template<class R> wrap<R const &> make_range(R const &r) { return r; }
template<class R> type_wrap<R> twrap(R &) { throw 0; }
template<class R> type_wrap<R const &> twrap(R const &) { throw 0; }
template<class T> T &move(T &v) { return v; }
template<class T> T const &move(T const &v) { return v; }
#endif
template<class R> wrap<typename RT<R>::It> begin(any const &r, type_wrap<R>)
{ return RT<R>::begin(static_cast<wrap<R> const &>(r).v); }
template<class R> wrap<typename RT<R>::It> end(any const &r, type_wrap<R>)
{ return RT<R>::end (static_cast<wrap<R> const &>(r).v); }
template<class R> bool equal(any const &i, any const &j, type_wrap<R>)
{ return static_cast<wrap<typename RT<R>::It> const &>(i).v == static_cast<wrap<typename RT<R>::It> const &>(j).v; }
template<class R> void advance(any const &i, typename std::iterator_traits<typename RT<R>::It>::difference_type const d, type_wrap<R>)
{ return std::advance(static_cast<wrap<typename RT<R>::It> const &>(i).v, d); }
template<class R> typename RT<R>::It &iter(any const &i, type_wrap<R>)
{ return static_cast<wrap<typename RT<R>::It> const &>(i).v; }
}
你可以用它喜歡:
#include <vector>
#include <iostream>
std::vector<int> make_vect()
{
std::vector<int> v;
v.push_back(5);
v.push_back(8);
v.push_back(10);
return v;
}
int main()
{
foreach (int c, make_vect())
{
std::cout << c << std::endl;
}
}
+0
但是,如果您有C++ 11可用,那麼編寫宏有什麼意義? –
+0
@MatthieuM .:如果你看看代碼,它應該是相當明顯的,它不需要C++ 11的工作。 – Mehrdad
+0
我只是在評論你的筆記*它也應該可以在GCC和MSVC中使用C++ 11的r值引用* –
相關問題
- 1. BOOST_STATIC_ASSERT沒有提升
- 2. Asio沒有提升
- 3. CMake沒有找到提升
- 4. 項目建設有和沒有提升
- 5. Parallel.ForEach和Regex沒有性能提升嗎?
- 6. gnuplot-iostream沒有鏈接到提升
- 7. 提升make_shared沒有模板參數
- 8. cmake沒有找到提升庫
- 9. boost ::線程沒有全部提升?
- 10. WampServer上的APC沒有性能提升
- 11. 爲什麼工具欄沒有提升?
- 12. enable_if +類型模板,沒有SFINAE(enable_if_c沒有提升?)
- 13. 使用存儲過程有沒有主要的性能提升?
- 14. 有沒有不需要提升的連接器/ C++庫?
- 15. C#TryParse有沒有提升lexical_cast等價物?
- 16. 用Webpack捆綁ES6類。有沒有辦法提升擴展類?
- 17. 有沒有辦法關閉提升日期和時間驗證
- 18. tortoiseSVN 1.8升級沒有升級svn.exe
- 19. 提升庫和持有值
- 20. 升壓program_options沒有找到
- 21. 提升線程和提升Asio
- 22. 提升爲Android建設提升日誌
- 23. 索引時間文件提升沒有考慮到
- 24. OPcache計數緩存命中,但沒有性能提升
- 25. 如何(交叉)編譯提升沒有python?
- 26. 管道提升:: iostreams沒有任何輸出
- 27. 提升緩衝成char *(沒有的std :: string)
- 28. 提升沒有共享內存的進程間字符串
- 29. 「沒有這樣的文件」包括問題與提升dynamic_bitset
- 30. 在與/函數的參數二進制搜索沒有提升
我不熟悉的加速,但可能的std ::從C++ 11是值得一試的for_each?另外,在C++ 11中,您可以編寫for(int x:vec){...} – Spook