我正致力于基因进化神经网络。我在2008年使用visual studio 2005编写了一个程序。现在我将程序转换为Eclipse(Linux)和VS 2013(Win)项目,并支持c ++ 11。运行后,两个项目都给出了同样的错误:
获取临时[-fpermissive]
的地址
经过大量搜索后发现,由于新的C ++标准不允许获取临时对象的地址,因此会出现此错误。因为所有对象都是使用“new”创建的(所以我猜它们应该始终可用)。我部分地想出了问题,但不知道如何解决它。如果你运行eclipse项目,它将突出显示项目中的两个错误。
由于需要完整的代码来检查所以我很难用语言来解释所以我在https://bitbucket.org/a-akram/geans.git的git上托管了eclipse项目,我让每个人都可以访问它。
主要问题是变量wp1
& wp2
。 m_vPopulatin
是包含神经网络地址的向量。
CNeuralNetwork* CGeneticEngine::Evolve()
{
CLearningEngine *l;
double totalError = 0.0;
for (int iter = 0;iter < CGN_MAXITER; iter++)
{
for (int i = 0;i < CGN_POPULATION; i++)
{
l = new CLearningEngine(m_vPopulation[i]);
l->Run(m_vTrainingDataset);
for(unsigned int p = 0; p < m_vTrainingDataset->size(); p++)
{
totalError = totalError + m_vPopulation[i]->getm_dTotalNetworkError();
totalError = totalError/m_vTrainingDataset->size();
}
if (totalError < CGN_THRESHOLD)
return m_vPopulation[i];
m_dErrors[i] = totalError;
}
SortFitnesses();
NewPopulation();
}
return NULL;
}
void CGeneticEngine::NewPopulation()
{
int id1, id2;
double temp;
std::vector <CSynapticConnection *> *wp1;
std::vector <CSynapticConnection *> *wp2;
for (int i=0;i<CGN_POPULATION / 2;i++)
{
id1 = rand() % CGN_POPULATION / 2;
id2 = rand() % CGN_POPULATION / 2 + CGN_POPULATION / 2;
wp1 = &m_vPopulation[id1]->getm_vListofSynaptics();
wp2 = &m_vPopulation[id2]->getm_vListofSynaptics();
// Cross over the weights.
for (int j = 0; j < 2; j++)
{
temp = (*wp1)[j+6]->getWeight();
(*wp1)[j+6]->setWeight((*wp2)[j+6]->getWeight() );
(*wp2)[j+6]->setWeight(temp);
}
// adding slight genetic change due to crossover randomly.
if (rand() % 10 < 2)
{
for(unsigned int j = 0; j < wp1->size();j++)
(*wp1)[j]->changeWeight((double)(rand())/(32767/2) - 1);
for(unsigned int j = 0; j < wp2->size();j++)
(*wp2)[j]->changeWeight((double)(rand())/(32767/2) - 1);
}
}
}
由于这是我在这个论坛上的第一个问题所以我可能没有说得好,所以我要求主持人暂时不要关闭它。如有必要,我会更清楚。但是随着项目文件的掌握,你们很容易找出问题和解决方案。
我将非常感谢您帮助解决问题...如果您需要任何进一步的信息,请与我们联系。
答案 0 :(得分:2)
首先考虑CNeuralNetwork
类的这个子集:
class CNeuralNetwork
{
// ...
public:
std::vector<CSynapticConnection *> getm_vListofSynaptics()
{
return m_vListofSynaptics;
}
std::vector<CSynapticConnection*> m_vListofSynaptics;
// ...
};
这里有一个getter(getm_vListofSynaptics()
),它返回一个临时值:公共数据成员m_vListofSynaptics
的副本。
在CGeneticEngine::NewPopulation()
函数中,您将获取临时对象的地址,这会触发错误:
wp1 = &m_vPopulation[id1]->getm_vListofSynaptics();
wp2 = &m_vPopulation[id2]->getm_vListofSynaptics();
(有关详细信息,请参阅Why is taking the address of a temporary illegal?。)
您需要考虑/应用一些更改:
getters / setter对于行为的封装/隐藏属性的内部表示是有用的(?),但是m_vListofSynaptics
是公共的,所以getter&#34;几乎没有购买任何东西&#34; (例如,请参阅Why use getters and setters? / Public Data members vs Getters, Setters了解情况)
关于错误,你可以(这只是一个&#34;快速修复&#34;,设计似乎可以改为完全避免吸气剂):
更改getter以便它返回一个指向数据成员的引用/指针(数据成员应该是私有的)
class CNeuralNetwork
{
// ...
public:
std::vector<CSynapticConnection *> *getm_vListofSynaptics()
{
return &m_vListofSynaptics;
}
private:
std::vector<CSynapticConnection*> m_vListofSynaptics;
};
直接访问m_vListofSynaptics
数据成员(可能不是一个好主意):
wp1 = &m_vPopulation[id1]->m_vListofSynaptics;
(看看If a variable has getter and setter, should it be public?)