boost :: optional <> funciona perfecto para tipos de datos simples pero tan pronto como se usa para una clase que hereda de una clase que implementa una interfaz, falla cuando se habilita el alias estricto.Por qué boost :: optional fail para clases que heredan funciones virtuales
Ejemplo:
#include <boost/optional.hpp>
struct MyLine{
double a;
double b;
};
class Edge{
public:
MyLine toMyLine() const;
private:
virtual MyLine doToMyLine() const =0;
};
class Wall:public Edge {
public:
Wall(MyLine const& seg):mMyLine(seg){};
private:
MyLine doToMyLine() const{return MyLine();};
MyLine mMyLine;
};
class SimpleWall {
public:
SimpleWall(MyLine const& seg):mMyLine(seg){};
private:
MyLine mMyLine;
};
int main(){
//boost::optional<Wall> res; //fails with strict aliasing error
boost::optional<SimpleWall> res2; //compiles just fine
}
compilado con la siguiente versión de gcc 4.4.3 usando este es el error:
g++ -c -pipe -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Werror -std=c++0x -O2 -Wall -W -I/usr/local/boost_1_44_0 -o obj/main.o main.cpp
¿Cuál es la mejor manera de resolver este problema. Me gustaría dejar activada la advertencia de alias estrictos. Estoy usando la versión de impulso 1.44.
ACTUALIZACIÓN:
Se pone peor !! Consideremos el siguiente código:
#include <boost/optional.hpp>
class MyBase{
public:
int toFoo() const;
private:
virtual int doToFoo() const =0;
};
class Child:public MyBase {
public:
Child(int const& foo):mFoo(foo){};
private:
int doToFoo() const{return 0;}
int mFoo;
};
int main(){
boost::optional<int> optint; //comment out for surprise
optint.get(); //comment out for surprise
boost::optional<Child> res2;
res2.get();
}
Compilado con la siguiente versión de gcc 4.4.3 usando este compila:
g++ -c -pipe -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Werror -std=c++0x -O2 -Wall -W -I/usr/local/boost_1_44_0 -o obj/main.o main.cpp
Si las líneas marcadas con "// comente para la sorpresa" están comentadas, me obtener una advertencia de aliasing estricta. Lo he comprobado al menos 20 veces. Esta es una de las cosas más extrañas que he visto. Parece que boost :: optional inicializa sth. independiente de su parámetro de plantilla o como gcc entendiendo boost :: opcional solo si se llama con sth. trivial primero. Algunas ideas ?
Dado que estamos hablando estrictamente aliasing, podemos suponer que está utilizando GCC? (Es el único compilador que conozco que sabe o le importa) –
@Martin: Pruebe Boost 1.46.1 o la versión beta 1.47 antes de hacer cualquier otra cosa; es bastante probable que esto ya se haya solucionado teniendo en cuenta que 1.44.0 tiene ahora casi un año. – ildjarn
¿Qué es la materia? ¿Hay algún problema de "aliasing estricto" en este código? – mattn