簡體   English   中英

形成錯誤的C ++ 0x代碼或編譯器錯誤?

[英]Ill-formed C++0x code or compiler bug?

在下面的C ++ 0x代碼中,我嘗試使用克隆成員函數(如果存在)克隆對象並回退到復制構造函數:

struct use_copy_ctor {};
struct prefer_clone_func : use_copy_ctor {};

template<class T>
auto clone(T const* ptr, prefer_clone_func)
-> decltype(ptr->clone())
{ return ptr->clone(); }

template<class T>
auto clone(T const* ptr, use_copy_ctor)
-> decltype(new T(*ptr))
{ return new T(*ptr); }

struct abc {
  virtual ~abc() {}
  virtual abc* clone() const =0;
};

struct derived : abc
{
  derived* clone() const { return new derived(*this); }
};

int main()
{
  derived d;
  abc* p = &d;
  abc* q = clone(p,prefer_clone_func());
  delete q;
}

我們的想法是使用auto ...-> decltype(expr)來清除不正確的表達式,作為模板參數推導(SFINAE)的一部分,並通過部分排序和第二個函數解決兩個克隆函數模板之間可能存在的歧義參數。

不幸的是,GCC 4.5.1不接受這個程序:

test.cpp: In function 'int main()':
test.cpp:28:39: error: cannot allocate an object of abstract type
  'abc'
test.cpp:14:12: note:   because the following virtual functions are
  pure within 'abc':
test.cpp:16:16: note:        virtual abc* abc::clone() const
test.cpp:28:39: error: cannot allocate an object of abstract type
  'abc'
test.cpp:14:12: note:   since type 'abc' has pure virtual functions

現在,問題是,這是一個編譯器錯誤還是我錯誤地認為SFINAE適用於此? 我會以一個堅實的推理來回答這個問題。

編輯:如果我將decltype(new T(*ptr))更改為T*則代碼編譯因為重載分辨率而更喜歡本例中的第一個函數模板。 但這違背了將表達式作為函數聲明的一部分的目的。 目的是使編譯器在出現錯誤時將功能從超載分辨率集中取出。

我遇到了與MSVC非常相似的問題,結果發現編譯器無法識別虛函數中的共變量返回類型。 嘗試將derived的clone定義更改為返回abc

我想我確信這實際上是一個編譯器錯誤並提交了一份報告 讓我們看看發生了什么。 作為解決方法, decltype(new T(*ptr))可以替換為T* 唯一的區別是函數模板將保留重載決策集的一部分,在這種情況下這不是一個大問題。

編輯 :順便說一下,我被告知clang ++接受上面的代碼。

暫無
暫無

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

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