boost :: option <> отлично работает для простых типов данных, но при использовании для класса, унаследованного от класса, реализующего интерфейс, происходит сбой при включении строгого алиасинга.
Пример:
#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
}
Скомпилировано с использованием gcc версии 4.4.3, ошибка:
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
Как лучше всего решить эту проблему. Я бы очень хотел оставить предупреждение о строгом псевдониме включенным. Я использую версию Boost 1.44.
UPDATE:
Становится хуже !! Рассмотрим следующий код:
#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();
}
Компилируется с использованием следующей версии gcc 4.4.3:
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
Если закомментированы строки, помеченные как «// комментарий для неожиданности», я получаю строгое предупреждение о псевдонимах. Я проверил это по крайней мере 20 раз. Это одна из самых странных вещей, которые я когда-либо видел. Похоже, boost :: необязательный инициализирует sth. не зависит от параметра шаблона или типа gcc, получающего понимание boost :: необязательно, только если вызывается с помощью sth. тривиально первое. Есть идеи?