0

次のようなクラスがあります。

class Particle()
{

    void CalcSomething(Super& arg){
        for(unsigned long long index = 0; index < arg.NumberOfParticle(); index ++){                              
            if(this != arg.ParticleMemoryPointer(index)){
                // Do the calculations
            }
        }
    }

}

そして、次のクラスは粒子を保持します。

class Super()
{

    const Particle* const ParticleMemoryPointer(unsigned int index)
    {
        std::list<Particle>::iterator iter = mParticles.begin();
        std::advance(iter, index);
        return &(*iter);
    }

    std::list<Particle> mParticles;
}

アイデアは、CalcSomething を呼び出している粒子のインスタンスが、関数内のインデックスによってアドレス指定されたものと同じ Particle のインスタンスから CalcSomething が呼び出されていることを検出する必要があるということCalcSomethingです。(それは意味がありますか?私はそれをうまく表現していません...)

この理由は、2 つの粒子間で計算を行う場合、それらが異なる粒子であることを確認する必要があるためです。

this一部の cout ステートメントは、ParticleMemoryPointer によって返されるメモリ アドレスが、リストに 1 つの項目がある場合のポインターと同じではないことを示しています。(それらは、1 つの項目で、同じ粒子で 2 回計算を行っているはずです。)

これが理解できることを願っています。

編集CalcSomething を呼び出す Super 内部の関数:

void Super::UpdateParticles(double time_step)
{
    std::list<Particle>::iterator iter = mParticles.begin();

    for(unsigned long long index = 0; index < mParticles.size(); index ++){
        std::advance(iter, 1);
        iter->CalcSomething(*this);
    }
}

編集 2 std::vector は使用できません。(私たちはあなたがそれを考えていたことを知っています!)

4

2 に答える 2

1

要素を に挿入した後list、そのリストとその要素が存在する限り、そのポインタが無効になることはありません。詳細については、この回答を参照してください: std::vector および std::list の要素へのポインター

リストに挿入した後、挿入されていない元の要素と挿入された要素を比較していないことを確認してください。挿入すると、要素がリストに移動またはコピーされます。

あなたの意図した目的のために、ポインターをチェックしなくても、Particleについて何も知る必要のない、より簡単な方法があると感じずにはいられません。Super

(疑似コード)

for particle in particles(start, end - 1):
    for otherParticle in particles(particle + 1, end)
        DoSomething(particle, otherParticle)
于 2013-02-27T23:43:38.057 に答える
0
template<typename Iter, typename Func>
void pair_wise(Iter it, Iter last, Func func) {
    while(it != last) {
        Iter other = it;
        ++other;
        while(other != last) {
            func(*it, *other);
            ++other;
        }
        ++it;
    }
}

これは、たとえば、4 つの値12、を反復処理し34それらをペアにします。

(1, 2), (1, 3), (1, 4)
(2, 3), (2, 4)
(3, 4)

C++11 のラムダ関数で使用できます。

int main() {
    list<Particle> particles;

    pair_wise(particles.begin(), particles.end(),
              [](Particle& lhs, Particle& rhs) {
                  lhs.doSomething(rhs);
              });                  
}

または、たとえば C++11 より前の関数ポインターを使用する場合:

void calcSomething(Particle& lhs, Particle& rhs) {
    lhs.calcSomething(rhs);
}

int main() {
    list<Particle> particles;

    pair_wise(particles.begin(), particles.end(),
              calcSomething);                  
}
于 2013-02-28T01:12:57.897 に答える