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

发布于 2024-11-16 16:34:33 字数 2036 浏览 3 评论 0原文

升压::可选<>非常适合简单数据类型,但一旦用于从实现接口的类继承的类,在启用严格别名时就会失败。

示例:

#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

如果标有“//comment out for opportunity”的行被注释掉,我会收到严格的别名警告。我已经检查了至少 20 次。这是我见过的最奇怪的事情之一。看起来 boost::Optional 初始化了一些东西。独立于它的模板参数,或者像 gcc 一样,只有在使用某项调用时才能理解 boost::Optional 。首先是微不足道的。有什么想法吗?

boost::optional<> works perfect for simple data types but as soon as used for a class inheriting from a class implementing an interface it fails when strict aliasing is enabled.

Example:

#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
}

Compiled with the following using gcc version 4.4.3 this is on 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

What is the best way to solve this problem. I would very much like to leave strict-aliasing warning enabled.I'm using boost version 1.44.

UPDATE:

It gets worse!! Consider the following code:

#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();
}

Compiled with the following using gcc version 4.4.3 this compiles:

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

If the lines marked with "//comment out for surprise" are commented out, I get a strict aliasing warning. I have checked this at least 20 times. This is among the weirdest things I ever saw. Looks like boost::optional initializes sth. independent from its template parameter or like gcc getting to understand boost::optional only if called with sth. trivial first. Any ideas ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

横笛休吹塞上声 2024-11-23 16:34:33

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

Segment doToSegment(){};

应该添加const:

Segment doToSegment() const {};

I tried that program in Boost 1.44.0.
This problem reason is don't override doToSegment.

Segment doToSegment(){};

should be add const:

Segment doToSegment() const {};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文