为什么对于继承虚函数的类,boost :: optional失败

Mar*_*tin 5 c++ gcc boost strict-aliasing gcc-warning

boost :: optional <>适用于简单的数据类型,但只要用于从实现接口的类继承的类,它就会在启用严格别名时失败.

例:

#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
}
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

解决这个问题的最佳方法是什么.我非常希望启用严格别名警告.我正在使用升级版本1.44.

更新:

它变得更糟!请考虑以下代码:

#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();
}
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

如果注释掉标有"//注释掉惊喜"的行,我会收到严格的别名警告.我已经检查了至少20次.这是我见过的最奇怪的事情之一.看起来像boost :: optional初始化某事.独立于其模板参数或像gcc一样,只有在用sth调用时才能理解boost :: optional.琐碎的.有任何想法吗 ?

Aki*_*shi 4

我在 Boost 1.44.0 中尝试了该程序。这个问题的原因是没有覆盖doToSegment。

Segment doToSegment(){};
Run Code Online (Sandbox Code Playgroud)

应该添加const:

Segment doToSegment() const {};
Run Code Online (Sandbox Code Playgroud)