C++ 为什么铿锵++;如果然后链接失败,对内联启用\u发出警告?

C++ 为什么铿锵++;如果然后链接失败,对内联启用\u发出警告?,c++,c++11,clang,enable-if,C++,C++11,Clang,Enable If,我在玩弄一个想法,遇到了一个让我挠头的问题。我希望在我开始将这个想法移植到一个更大的框架之前,有人能给我一个清晰(最好是引用)的解释 我正在进行以下实验: /* * 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> #incl

我在玩弄一个想法,遇到了一个让我挠头的问题。我希望在我开始将这个想法移植到一个更大的框架之前,有人能给我一个清晰(最好是引用)的解释

我正在进行以下实验:

/*
 * 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());
};
/*
*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
*/
#包括
#包括
模板
结构是可比较的{
静态constexpr bool value=(std::is_integral::value&&std::is_integral::value)|(std::is_floating_point::value&&std::is_floating_point::value);
};
模板
课间休息{
公众:
内联区间();
内联间隔(常数T&x);
在线间隔(常数T和最小值、常数T和最大值);
公众:
模板
constexpr typename std::enable_if::value,bool>::type
运算符==(常数间隔&)常数无异常;
模板
内联类型名称std::enable_if::type
运算符==(常数间隔&)常数无异常;
内联布尔运算符!=(常数T&rhs)常数noexcept;
模板
constexpr typename std::enable_if::value,bool>::type
运算符!=(常数间隔&)常数无异常;
模板
内联类型名称std::enable_if::type
运算符!=(常数间隔和rhs)常数无异常;
公众:
内联T&max()无异常;
内联T常量&max()常量noexcept;
内联T&min()无例外;
内联T const&min()const noexcept;
受保护的:
T min_;
T最大值;
};
#包括
#包括
使用名称空间std;
int main(int argc,字符**argv){
间隔a(0,25);
区间b(0,25);
区间c(0,25);
间隔d(0,25);
cout
main.cc:24:4:警告:未定义内联函数“interval::operator==”[-Wundefined inline]
运算符==(常数间隔&)常数无异常;
^
main.cc:57:22:注:此处使用

“a==c=“我真傻。我花了最后一个小时+无缘无故地搔头

我使用GCCWaaay的时间太长了(最近刚切换到clang)

警告告诉我它没有定义,因为它没有定义。它们在下面定义
main()
。似乎gcc/vc++做了预扫描,所以它们被定义了,尽管严格来说,它们不应该被定义

我刚把
main()
移到底部,瞧


我想这一切都是我用stackoverflow作为一个试探板来解决我自己的问题。

这和问题是同一个问题,尽管不管出于什么原因gcc似乎正在实例化模板,但我的直觉是clang是正确的,模板定义必须在使用模板的地方可见。您也可以显式地在下面的
main
中实例化所需的模板,但确保定义在使用之前出现当然更好。@user657267这是我得出的结论(见我自己的答案)。我使用的叮当声越多,我越喜欢它,但摆脱gcc给我的多年习惯需要时间。
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 <<
                                          ^