考虑在头文件中定义的库
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button"
android:theme="@style/PrimaryDarkButton" />
库被编译,我现在正在开发一个链接到这个库的应用程序。我想很长一段时间它都是某种可见性问题,但即使在无处不在的地方添加struct Proj {
struct Depth {
static constexpr unsigned Width = 10u;
static constexpr unsigned Height = 10u;
};
struct Video {
static constexpr unsigned Width = 10u;
static constexpr unsigned Height = 10u;
};
};
(来自CMake的标准可见性内容)之后,我终于找到了问题。
B_EXPORT
我甚至无法使用小型虚拟库/示例应用程序重现该问题。但是在应用程序中使用template <class Projection>
struct SomeApplication {
SomeApplication() {
unsigned height = std::max(// or std::max<unsigned>
Projection::Depth::Height,
Projection::Video::Height
);
}
};
会导致链接错误,而如果我自己执行此操作
std::max
一切顺利。就使用unsigned height = Projection::Depth::Height;
if (height < Projection::Video::Height)
height = Projection::Video::Height;
而言,可见性方面似乎没有任何具体问题。
有关可能导致此问题的任何想法?这是在OSX上,所以this doesn't even apply。
答案 0 :(得分:1)
问题是Width
和Height
已声明,而不是struct
中已定义。实际上,这意味着没有为他们分配存储空间。
现在回想一下std::max
的签名:
template<typename T>
const T& max(const T&, const T&);
注意引用:这意味着要采用参数的地址。但是,由于Width
和Height
仅被声明,因此它们没有任何存储空间!因此链接器错误。
现在让我们考虑你的其余问题。
您手写的max
有效,因为您从不接受任何指针或对变量的引用。
您可能无法在玩具示例中重现这一点,因为特别是根据优化级别,足够智能的编译器可能会在编译时评估max
并省去在运行时获取地址的麻烦。例如,比较gcc 7.2的no optimization与-O2的dis:评估确实是在编译时完成的!
至于修复,取决于。您有几个选项,仅举几例: