将模板类型传递给函数并使用局部变量赋值c ++

时间:2015-12-28 14:26:33

标签: c++ templates assignment-operator template-function

我有以下代码:

template<typename T> void computeFractalDimensionData(RandomWalkMethods::LatticeType latticeType, gsl_rng* randNumGen) {

    int nD = 0;

    // if T is of type std::pair<int,int> then set no. of dimensions to 2
    if (typeid(T) == typeid(std::pair<int, int>)) {
        nD = 2;
    }

    // else if T is of type RWM::Triple<int,int,int> then set no. of dimensions to 3
    else if (typeid(T) == typeid(RandomWalkMethods::Triple<int, int, int>)) {
        nD = 3;
    }

    else {
        return;
    }

    // Create vector of T structs to store DLA structure results
    std::vector<T> aggResults;

    // Initialise particle spawning type and attractor type for DLA system
    RandomWalkMethods::ParticleSpawnType spawn = RandomWalkMethods::CONSTANT_RANDOM_BOUNDINGBOX_EDGE;
    RandomWalkMethods::AttractorDLAType attractor = RandomWalkMethods::POINT;

    // Under-estimate for fractal dimension of the DLA
    const double fractalDimUnderestimateRecip = 1 / 1.65;

    for (int i = 100; i <= 1000; i += 100) {

        // initialise spawnDiameter using: exp(log(n)/fDUR) = n^{1/fDUR}
        int spawnDiam = 2*static_cast<int>(std::pow(i, fractalDimUnderestimateRecip));

        // if system is 2-dimensional, compute DLA for 2D on given lattice
        if (nD == 2) {
            aggResults = RandomWalkMethods::diffusionLimitedAggregateRandomWalk2D(i, spawn, spawnDiam, latticeType, randNumGen, attractor);
        }

        // else if system is 3 dimensional, compute DLA for 3D on given lattice
        else if (nD == 3) {
            aggResults = RandomWalkMethods::diffusionLimitedAggregateRandomWalk3D(i, spawn, spawnDiam, latticeType, randNumGen, attractor);
        }

        // compute the minimum bounding radius which encloses all particles in the DLA structure
        double boundingRadius = std::sqrt(maxMagnitudeVectorOfMultiples< double, T >(aggResults));

    }


}

我可以用

等声明来打电话
computeFractalDimensionData< std::pair<int,int> >(lattice, randNumGen);

computeFractalDimensionData< RandomWalkMethods::Triple<int,int,int> >(lattice, randNumGen);    

其中Triple只是我用3个元素定义的结构(与std::pair基本相同,但扩展为3个字段)。此外,函数diffusionLimitedAggregateRandomWalk2DdiffusionLimitedAggregateRandomWalk3D分别返回std::vector<std::pair<int,int>>std::vector<Triple<int,int,int>>的类型。

问题在于,当我使用上述任一语句调用时,我会收到以下错误(发生在赋值语句aggResults = ...):

binary '=': no operator found which takes a right-hand operand of type 'std::vector<std::pair<int,int>,std::allocator<_Ty>>' (or there is no acceptable conversion)

同样适用于Triple<int,int,int>的情况。据我所知,这意味着我需要为这两个结构重载赋值运算符 - 但我不认为这是问题,因为以下语句在我的程序之前已经正确使用:

std::vector< std::pair<int,int> > aggResults = RandomWalkMethods::diffusionLimitedAggregateRandomWalk2D(nParticles, boundingBox, spawnDiam, latticeType, randNumGen, attractor, &diffLimAggFile);

所以我知道我可以将DLA方法的结果分配给正确类型的变量,但是如果我通过使用将类型传递给模板函数来尝试它,则编译器会抱怨,如上所示。

这里发生了什么,我将如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

这来自

的事实
aggResults = diffusionLimitedAggregateRandomWalk2D(i, spawn, spawnDiam, latticeType, randNumGen, attractor);
如果aggResultsstd::vector<T>T返回Triple<int, int, int>,则编译diffusionLimitedAggregateRandomWalk2Dstd::vector<std::pair<int, int>>

建议的解决方案:声明一个模板化的函数,并将其专门用于某些T

template<typename T>
void computeFractalDimensionData(RandomWalkMethods::LatticeType latticeType, gsl_rng* randNumGen);

template<>
void computeFractalDimensionData<std::pair<int, int>>(RandomWalkMethods::LatticeType latticeType, gsl_rng* randNumGen)
{
    // ...
}

template<>
void computeFractalDimensionData<Triple<int, int, int>>(RandomWalkMethods::LatticeType latticeType, gsl_rng* randNumGen)
{
    // ...
}

它使代码更易读,并且无法使用帮助编译错误编译以下行:

computeFractalDimensionData<void>(lattice, randNumGen);

答案 1 :(得分:2)

YSC的解决方案很好。我希望您注意到您的函数中的以下代码是错误的模板使用:

if (nd == ...)

模板用于静态多态,您在模板函数中使用动态代码(这些dimension)。正确使用静态多态可能会引入模板参数/Swagger