boost :: optional <>对于简单的数据类型是完美的,但只要用于从类实现接口的类继承,它会在启用严格别名时失败。为什么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
什么是解决这个问题的最好办法。我非常想离开strict-aliasing警告enabled.I'm使用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次。这是我见过的最奇怪的事情之一。看起来像boost :: optional初始化某事物。独立于其模板参数或像gcc一样理解boost ::只有在使用某种方法调用时才可选。微不足道的第一。有任何想法吗 ?
既然你谈论严格别名,我们可以假设你使用GCC? (这是我知道的唯一一个知道或知道的编译器) –
@Martin:在做任何其他事情之前,尝试Boost 1.46.1或1.47测试版;考虑到1.44.0现在已经快一年了,很可能已经确定了这一点。 – ildjarn
什么是重要?此代码中是否存在“严格别名”的问题? – mattn