5

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
}

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 を使用しています。

アップデート:

ひどくなる!!次のコードを検討してください。

#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回チェックしました。これは私が今まで見た中で最も奇妙なものの 1 つです。boost::optional が sth を初期化するように見えます。テンプレートパラメータから独立したり、sth で呼び出された場合にのみ boost::optional を理解するようになる gcc のように。最初に些細なこと。何か案は ?

4

1 に答える 1

4

Boost 1.44.0でそのプログラムを試しました。この問題の理由は、doToSegment をオーバーライドしないことです。

Segment doToSegment(){};

const を追加する必要があります。

Segment doToSegment() const {};
于 2011-06-22T02:18:43.743 に答える