Je ne sais pas une solution générale mais vous pouvez résoudre votre problème (utilisez la première ou la deuxième ou la troisième index ou ...) en utilisant une référence.
Dans le cas 3D, d'abord, vous pouvez déclarer les variables de boucle (i
, j
et k
)
std::size_t i, j, k;
Ensuite, vous pouvez "lien" une autre variable (r
) à i
, j
ou k
selon un La valeur de modèle I
std::size_t & r = (I == 0U ? i : (I == 1U ? j : k));
Ce qui suit est un exemple compilable
#include <vector>
#include <iostream>
template <std::size_t I>
void func (std::vector<std::vector<std::vector<double> > > & d)
{
std::size_t i, j, k;
std::size_t & r = (I == 0U ? i : (I == 1U ? j : k));
for (i = 0U ; i < d.size() ; ++i)
for (j = 0U ; j < d[i].size() ; ++j)
for (k = 0U ; k < d[i][j].size() ; ++k)
d[i][j][k] += r+1;
}
int main()
{
std::vector<std::vector<std::vector<double> > > data;
// some data in data
func<0>(data); // r is i
func<1>(data); // r is j
func<2>(data); // r is k
}
--- EDIT ---
L'OP demander
est là de toute façon que cette fonction pourrait travailler pour la dimension arbitraire?
No.
Non cette fonction.
Mais je propose une solution complètement différente (et plus complexe). Je l'écris mais ne me demande pas de vérifier si cela fonctionne vraiment.
L'idée n'est plus basée sur la référence mais sur la spécialisation du template.
Cette fois, l'index de modèle est 1-basé: utiliser la valeur du modèle 1
si vous voulez intercepter le premier indice (ex x
), 2
si vous voulez intercepter le second index (ex y
), etc.
Alors vous appelez
foo<1U>(data1); // r is the first index
pour un vecteur 1D,
pour un vecteur 2D, etc. .
Si vous appelez
foo<I>(data)
où I
est plus grande que la dimension de data
, vous obtenez une erreur de compilation.
Si vous appelez
foo<0>(data)
vous obtenez une erreur de compilation, mais seulement si vous compilez C++ 11 ou plus récent (avec 98 r
C++ deviennent zéro, mais vous pouvez ajouter un assert()
pour obtenir une exécution Erreur).
L'exemple
#include <vector>
#include <iostream>
template <std::size_t I>
struct bar
{
template <typename T>
static void baz (std::vector<T> & v, std::size_t)
{
for (std::size_t i = 0U ; i < v.size() ; ++i)
bar<I-1U>::baz(v[i], i);
}
};
template <>
struct bar<0U>
{
template <typename T>
static void baz (std::vector<T> & v, std::size_t r)
{
for (std::size_t i = 0U ; i < v.size() ; ++i)
baz(v[i], r);
}
static void baz (double & d, std::size_t r)
{ d += r + 1U; }
};
template <std::size_t I, typename V>
void foo (V & v)
{
#if __cplusplus >= 201103L
static_assert(I > 0U, "!"); // c++11 or newer
#endif
bar<I>::baz(v, 0U);
}
int main()
{
std::vector<double > data1;
std::vector<std::vector<double> > data2;
std::vector<std::vector<std::vector<double> > > data3;
// some data in data1, data2 and data3
// foo<0U>(data1); // compilation error in C++11 or newer
foo<1U>(data1); // r is the first index
// foo<2U>(data1); // compilation error
// foo<0U>(data2); // compilation error in C++11 or newer
foo<1U>(data2); // r is the first index
foo<2U>(data2); // r is the second index
// foo<3U>(data2); // compilation error
// foo<0U>(data3); // compilation error in C++11 or newer
foo<1U>(data3); // r is the first index
foo<2U>(data3); // r is the second index
foo<3U>(data3); // r is the third index
// foo<4U>(data3); // compilation error
}
Y at-il de toute façon que cette fonction pourrait travailler pour la dimension arbitraire? –
@DiMiao - réponse améliorée; J'espère que cela t'aides. – max66
Thx, votre méthode me donne une bonne direction pour mon problème. C'est vraiment utile. –