我有一个3x3的二维数组。我想访问它的所有元素。这可能吗?我这样做:
int myArray[3][3]; for(int &i: myArray){ //MY CODE HERE. }
但当我这样做时,我得到错误:
error: C2440: 'initializing' : cannot convert from 'int [3]' to 'int &'
我还在Qt 5.0 x64上使用MSVC++ 2012编译器。如果可以这样做,那么我如何获得每个元素的索引号?
vyu0f0g11#
只需使用auto关键字
auto
int myArray[3][3]; for(auto& rows: myArray) // Iterating over rows { for(auto& elem: rows) { // do some stuff } }
xpszyzbs2#
如果你只想在一个循环中遍历所有元素,那么你可以做如下的事情(C++11):
#include <type_traits> #include <algorithm> #include <cstdint> #include <cstdlib> #include <cstdio> #if defined(__clang__) # define UTILITY_COMPILER_CXX_CLANG # define UTILITY_COMPILER_CXX_VERSION __clang_major__ # define UTILITY_COMPILER_CXX_VERSION_MINOR __clang_minor__ # define UTILITY_COMPILER_CXX_VERSION_PATCHLEVEL __clang_patchlevel__ # if __clang_major__ < 3 # error unsuported clang version # endif #elif defined(__GNUC__) # define UTILITY_COMPILER_CXX_GCC # define UTILITY_COMPILER_CXX_VERSION __GNUC__ # define UTILITY_COMPILER_CXX_VERSION_MINOR __GNUC_MINOR__ # define UTILITY_COMPILER_CXX_VERSION_PATCHLEVEL __GNUC_PATCHLEVEL__ # if __GNUC__ < 4 # error unsuported gcc version # endif #elif defined(_MSC_VER) # define UTILITY_COMPILER_CXX_MSC # define UTILITY_COMPILER_CXX_VERSION _MSC_VER #else # error unknown compiler #endif #ifdef UTILITY_COMPILER_CXX_MSC # if UTILITY_COMPILER_CXX_VERSION >= 1900 # define UTILITY_PLATFORM_FEATURE_CXX_STANDARD_CONSTEXPR # endif #else # if __cplusplus >= 201103L # ifdef UTILITY_COMPILER_CXX_GCC // specific case for GCC 4.7.x and lower # if UTILITY_COMPILER_CXX_VERSION >= 5 || \ UTILITY_COMPILER_CXX_VERSION == 4 && UTILITY_COMPILER_CXX_VERSION_MINOR >= 8 # define UTILITY_PLATFORM_FEATURE_CXX_STANDARD_CONSTEXPR # endif # else # define UTILITY_PLATFORM_FEATURE_CXX_STANDARD_CONSTEXPR # endif # endif #endif #ifdef UTILITY_PLATFORM_FEATURE_CXX_STANDARD_CONSTEXPR # define CONSTEXPR constexpr #else # define CONSTEXPR #endif namespace utility { // bool identity / identities template <bool b> struct bool_identity { using type = bool; static CONSTEXPR const bool value = b; }; template <bool b> CONSTEXPR const bool bool_identity<b>::value; // Unrolled breakable `for_each` for multidimensional arrays namespace detail { template<bool is_array> struct _for_each_unroll { template <typename Functor, typename T, std::size_t N> _for_each_unroll(_for_each_unroll * parent_, T (& arr)[N], Functor && f) : parent(parent_), break_(false) { invoke(arr, std::forward<Functor>(f)); } template <typename Functor, typename T, std::size_t N> _for_each_unroll(_for_each_unroll * parent_, T (&& arr)[N], Functor && f) : parent(parent_), break_(false) { invoke(std::forward<T[N]>(arr), std::forward<Functor>(f)); } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> typename std::enable_if<I == N, void>::type invoke(T (& arr)[N], Functor && f) { } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> typename std::enable_if<I == N, void>::type invoke(T (&& arr)[N], Functor && f) { } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> typename std::enable_if<I < N, void>::type invoke(T (& arr)[N], Functor && f) { if (!break_) { _for_each_unroll<std::is_array<T>::value> nested_for_each{ this, arr[I], std::forward<Functor>(f) }; if (!nested_for_each.break_) { invoke<I + 1, Functor, T, N>(arr, std::forward<Functor>(f)); } else if (parent) parent->break_ = true; } } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> typename std::enable_if<I < N, void>::type invoke(T (&& arr)[N], Functor && f) { if (!break_) { _for_each_unroll<std::is_array<T>::value> nested_for_each{ this, std::forward<T>(arr[I]), std::forward<Functor>(f) }; if (!nested_for_each.break_) { invoke<I + 1, Functor, T, N>(arr, std::forward<Functor>(f)); } else if (parent) parent->break_ = true; } } _for_each_unroll * parent; bool break_; }; template <typename Functor, typename T, bool is_array> inline void _invoke_breakable(_for_each_unroll<is_array> & this_, const T & value, Functor && f, bool_identity<false> is_breakable) { f(value); }; template <typename Functor, typename T, bool is_array> inline void _invoke_breakable(_for_each_unroll<is_array> & this_, const T & value, Functor && f, bool_identity<true> is_breakable) { if (!f(value)) { this_.break_ = true; } }; template <typename Functor, typename T, bool is_array> inline void _invoke_breakable(_for_each_unroll<is_array> & this_, T && value, Functor && f, bool_identity<false> is_breakable) { f(std::forward<T>(value)); }; template <typename Functor, typename T, bool is_array> inline void _invoke_breakable(_for_each_unroll<is_array> & this_, T && value, Functor && f, bool_identity<true> is_breakable) { if (!f(std::forward<T>(value))) { this_.break_ = true; } }; template<> struct _for_each_unroll<false> { template <typename Functor, typename T> _for_each_unroll(void * parent, const T & value, Functor && f) : break_(false) { _invoke_breakable(*this, value, std::forward<Functor>(f), bool_identity<!std::is_void<decltype(f(value))>::value>{}); } template <typename Functor, typename T> _for_each_unroll(void * parent, T && value, Functor && f) : break_(false) { _invoke_breakable(*this, value, std::forward<Functor>(f), bool_identity<!std::is_void<decltype(f(std::forward<T>(value)))>::value>{}); } bool break_; }; } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> inline typename std::enable_if<I == N, void>::type for_each_unroll(T (& arr)[N], Functor && f) { } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> inline typename std::enable_if<I == N, void>::type for_each_unroll(T (&& arr)[N], Functor && f) { } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> inline typename std::enable_if<I < N, void>::type for_each_unroll(T (& arr)[N], Functor && f) { detail::_for_each_unroll<std::is_array<T>::value> nested_for_each{ nullptr, arr[I], std::forward<Functor>(f) }; if (!nested_for_each.break_) { for_each_unroll<I + 1, Functor, T, N>(arr, std::forward<Functor>(f)); } } template <std::size_t I = 0, typename Functor, typename T, std::size_t N> inline typename std::enable_if<I < N, void>::type for_each_unroll(T (&& arr)[N], Functor && f) { detail::_for_each_unroll<std::is_array<T>::value> nested_for_each{ nullptr, std::forward<T>(arr[I]), std::forward<Functor>(f) }; if (!nested_for_each.break_) { for_each_unroll<I + 1, Functor, T, N>(std::forward<T[N]>(arr), std::forward<Functor>(f)); } } }
int main() { int i = 0; int a[2][3][4] = { 0 }; utility::for_each_unroll(a, [&](int & value) { value = i; i++; }); for (auto & j0 : a) for (auto & j1 : j0) for (auto & j2 : j1) printf("%u ", j2); puts("\n"); i = 0; int b[2][3][4] = { 0 }; utility::for_each_unroll(b, [&](int & value) { value = i; i++; if (i >= 3) return false; return true; }); for (auto & j0 : b) for (auto & j1 : j0) for (auto & j2 : j1) printf("%u ", j2); }
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
https://godbolt.org/z/oEPf4GMsz
68de4m5k3#
#include <iostream> using namespace std; int main() { int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; for (auto &i : a) { for (auto &j : i) { cout << j << " "; } cout << endl; } }
jvlzgdj94#
把int*换成int&就行了
int*
int&
int myArray[3][3]; for(int* rows: myArray) // Iterating over rows { for(int* elem: rows) { // do some stuff } }
4条答案
按热度按时间vyu0f0g11#
只需使用
auto
关键字xpszyzbs2#
如果你只想在一个循环中遍历所有元素,那么你可以做如下的事情(C++11):
https://godbolt.org/z/oEPf4GMsz
68de4m5k3#
jvlzgdj94#
把
int*
换成int&
就行了