簡體   English   中英

g ++編譯錯誤在msvs中有效的另一件事

[英]g++ compilation error of another thing that works in msvs

大家好 我正在從一個主要在MSVS中開發的項目中移植一些代碼以使用g ++。 我發現很多細微的差別,大部分是MSVS允許的,而g ++不允許。 通常,它涉及c ++標准,MSVS可以讓它們滑動,但是我很難看到一個特定部分到底出了什么問題。

g ++在匹配對運算符!=的調用時遇到麻煩,但僅在特定情況下才可以。 如果宿主類不是模板,則查找特定嵌套類的運算符!=即可。 但是,如果我將托管類轉換為類模板,則一切都會中斷。 我或者缺少了c ++的基礎知識,或者g ++做錯了什么。

我學會了不要哭“編譯器錯誤!”。 太頻繁了,所以我想看看這里是否有人可以看到我所缺少的東西。

此工作示例顯示了有效的非模板版本,然后顯示了損壞的模板版本。 g ++ --version提供:g ++(Ubuntu 4.4.1-4ubuntu9)4.4.1

沒有模板的工作參考版本

namespace Works {

struct host {
    struct iterator {};
    iterator op();
};

bool operator != (host::iterator const& a0, host::iterator const& a1);

bool f() {
    return host().op() != host().op();
}

} // namespace Works

模板版本破損

namespace Broken {

template <typename T>
struct host {
    struct iterator {};
    iterator op();
};

template <typename T>
bool operator != (typename host<T>::iterator const& a0, 
                   typename host<T>::iterator const& a1);

bool f() {
    return host<int>().op() != host<int>().op();
}

} // namespace Broken

模板版本因以下錯誤而失敗:

Main.cpp: In function ‘bool Broken::f()’:
Main.cpp:50: error: no match for ‘operator!=’ in ‘Broken::host<int>().Broken::host<T>::op [with T = int]() != Broken::host<int>().Broken::host<T>::op [with T = int]()’

這不適用於msvc和gcc。

問題是在host<T>::iteratorT在不可推論的上下文中。 由於兩個參數都不允許推導T ,因此無法實例化功能模板。

這就是為什么通常在類中定義重載運算符。

struct iterator
{
    friend bool operator != (iterator const & lhs, iterator const & rhs)
    {
        return false;
    }
};

我打了類似的事情。 C ++運算符重載應該采用const輸入。 msvc將使您擺脫使用非const輸入的麻煩。 G ++堅持認為它們是const

構建一個@avakar的答案,盡管有些奇怪,但我的代碼可以正常工作:

namespace Broken {

template <typename T> struct host;

template <typename T>
bool operator != (typename host<T>::iterator const& a0,
                  typename host<T>::iterator const& a1);

template <typename T>
struct host {
    struct iterator {
       friend bool operator !=(iterator const & lhs, iterator const & rhs) {
          return operator !=<int>(lhs, rhs);
       }
    };
    iterator op();
};

bool f() {
    // The following does indeed end up calling the operator != you want it to call.  I
    // have a slightly different version in which I tested this.
    return host<int>().op() != host<int>().op();
}

} // namespace Broken

這就解決了以下問題:頂級operator !=的模板參數無法通過使用好友函數中的顯式模板參數進行調用來推導。 它需要向前聲明host模板。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM