我正在考虑一个想法,但遇到了一个令我百思不得其解的问题。我希望在我开始将这个想法迁移到更大的框架之前,有人能给我一个清晰的(最好是引用的)解释。
我正在运行以下实验:
/*
* gcc -Wall -O0 -g -std=c++11 main.cc -lstdc++ -lm -o mathras
* clang++ -Wall -O0 -g -std=c++11 main.cc -lstdc++ -lm -o mathras
*/
#include <type_traits>
#include <functional>
template<typename U, typename V>
struct is_comparable {
static constexpr bool value = (std::is_integral<U>::value && std::is_integral<V>::value) || (std::is_floating_point<U>::value && std::is_floating_point<V>::value);
};
template<typename T>
class interval {
public:
inline interval();
inline interval(const T& x);
inline interval(const T& min, const T& max);
public:
template<typename U>
constexpr typename std::enable_if<!is_comparable<T, U>::value, bool>::type
operator==(const interval<U>&) const noexcept;
template<typename U>
inline typename std::enable_if<is_comparable<T, U>::value, bool>::type
operator==(const interval<U>&) const noexcept;
inline bool operator!=(const T& rhs) const noexcept;
template<typename U>
constexpr typename std::enable_if<!is_comparable<T, U>::value, bool>::type
operator!=(const interval<U>&) const noexcept;
template<typename U>
inline typename std::enable_if<is_comparable<T, U>::value, bool>::type
operator!=(const interval<U>& rhs) const noexcept;
public:
inline T& max() noexcept;
inline T const& max() const noexcept;
inline T& min() noexcept;
inline T const& min() const noexcept;
protected:
T min_;
T max_;
};
#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, char** argv) {
interval<int> a(0, 25);
interval<unsigned> b(0, 25);
interval<float> c(0, 25);
interval<double> d(0, 25);
cout << boolalpha <<
"a == b = " << (a == b) << endl <<
"a != b = " << (a != b) << endl <<
"a == c = " << (a == c) << endl <<
"a != c = " << (a != c) << endl <<
"a == d = " << (a == d) << endl <<
"a != d = " << (a != d) << endl <<
"b == c = " << (b == c) << endl <<
"b != c = " << (b != c) << endl <<
"b == d = " << (b == d) << endl <<
"b != d = " << (b != d) << endl <<
"c == d = " << (c == d) << endl <<
"c != d = " << (c != d) << endl <<
flush;
return 0;
};
template<typename T>
inline interval<T>::interval():
min_(),
max_()
{ };
template<typename T>
inline interval<T>::interval(const T& x):
interval(x, x)
{ };
template<typename T>
inline interval<T>::interval(const T& min, const T& max):
min_((max < min) ? max : min),
max_((min > max) ? min : max)
{ };
template<typename T>
inline T& interval<T>::max() noexcept {
return this->max_;
};
template<typename T>
inline T const& interval<T>::max() const noexcept {
return this->max_;
};
template<typename T>
inline T& interval<T>::min() noexcept {
};
template<typename T>
inline T const& interval<T>::min() const noexcept {
return this->min_;
};
template<typename T>
template<typename U>
constexpr typename std::enable_if<!is_comparable<T, U>::value, bool>::type
interval<T>::operator==(const interval<U>&) const noexcept {
return false;
};
template<typename T>
template<typename U>
inline typename std::enable_if<is_comparable<T, U>::value, bool>::type
interval<T>::operator==(const interval<U>& rhs) const noexcept {
return (this->min_ == rhs.min()) && (this->max_ == rhs.max());
};
template<typename T>
template<typename U>
constexpr typename std::enable_if<!is_comparable<T, U>::value, bool>::type
interval<T>::operator!=(const interval<U>&) const noexcept {
return true;
};
template<typename T>
template<typename U>
inline typename std::enable_if<is_comparable<T, U>::value, bool>::type
interval<T>::operator!=(const interval<U>& rhs) const noexcept {
return (this->min_ != rhs.min()) || (this->max_ != rhs.max());
};
正如您所看到的,这看起来非常简单。 is_comparable 确定某个区间的两个数字是否具有可比性,然后类区间通过enable_if 使用该值来专门进行比较。
gcc 和 vc++(根据 http://webcompiler.cloudapp.net/ )都不会提示。它们都对无符号与有符号的比较发出警告(适当且符合预期),但继续编译、链接并生成预期的输出。
这就是让我摸不着头脑的原因。 Clang 并不提示签名。相反,它会产生以下警告...
main.cc:24:4: warning: inline function 'interval<int>::operator==<float>' is not defined [-Wundefined-inline]
operator==(const interval<U>&) const noexcept;
^
main.cc:57:22: note: used here
"a == c = " << (a == c) << endl <<
^
main.cc:31:4: warning: inline function 'interval<int>::operator!=<float>' is not defined [-Wundefined-inline]
operator!=(const interval<U>&) const noexcept;
^
main.cc:58:22: note: used here
"a != c = " << (a != c) << endl <<
^
main.cc:24:4: warning: inline function 'interval<int>::operator==<double>' is not defined [-Wundefined-inline]
operator==(const interval<U>&) const noexcept;
^
main.cc:59:22: note: used here
"a == d = " << (a == d) << endl <<
^
main.cc:31:4: warning: inline function 'interval<int>::operator!=<double>' is not defined [-Wundefined-inline]
operator!=(const interval<U>&) const noexcept;
^
main.cc:60:22: note: used here
"a != d = " << (a != d) << endl <<
^
main.cc:24:4: warning: inline function 'interval<unsigned int>::operator==<float>' is not defined [-Wundefined-inline]
operator==(const interval<U>&) const noexcept;
^
main.cc:61:22: note: used here
"b == c = " << (b == c) << endl <<
^
main.cc:31:4: warning: inline function 'interval<unsigned int>::operator!=<float>' is not defined [-Wundefined-inline]
operator!=(const interval<U>&) const noexcept;
^
main.cc:62:22: note: used here
"b != c = " << (b != c) << endl <<
^
main.cc:24:4: warning: inline function 'interval<unsigned int>::operator==<double>' is not defined [-Wundefined-inline]
operator==(const interval<U>&) const noexcept;
^
main.cc:63:22: note: used here
"b == d = " << (b == d) << endl <<
^
main.cc:31:4: warning: inline function 'interval<unsigned int>::operator!=<double>' is not defined [-Wundefined-inline]
operator!=(const interval<U>&) const noexcept;
^
main.cc:64:22: note: used here
"b != d = " << (b != d) << endl <<
^
根据警告,它似乎并没有提示任何与 interval<U>
有关的事情。 ,而是U
本身,除非这只是警告输出中的一个怪癖。
无论如何,它都会编译,但是在链接时,会在它首先未能内联的 undefined reference 上出错。
我用 clang 3.3 和 3.4 尝试过,结果相同。
第一个问题。为什么?我的代码对我来说看起来不错(忽略诸如签名之类的预期内容)。我实际上是否在 clang 发现的某个地方犯了一个重大错误(其他编译器实际上也有 bug),或者 clang 只是在这方面有 bug?
第二个问题。不管为什么,完成这个任务最适合交叉编译器的方法是什么?
最佳答案
愚蠢的我。花了最后一个小时+无缘无故地挠头。
我使用 gcc waaaay 太久了(最近才改用 clang)。
警告告诉我它没有定义,因为它没有定义。它们在 main()
下面定义。似乎 gcc/vc++ 进行了预扫描,因此它们被定义,尽管严格来说,它们不应该被定义。
我刚刚将 main()
移动到底部,瞧。
我想我所需要的只是使用 stackoverflow 作为共鸣板来解决我自己的问题。
关于c++ - 为什么 clang++ 会对内联的 enable_if 发出警告,然后无法链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27979080/