2014-12-04 18 views
10
kod aşağıda gcc-4.8.2

Clang - varsayılan değerle parametresi tarafından takip Değişkin şablon parametre paketi GCC 4.8 çalışır ancak clang değil 3.5

#include <iostream> 
using namespace std; 

template<typename... Args> 
void func(Args... args, int optional = 0) 
{ 
    cout << optional << endl; 
} 

int main() 
{ 
    func(1); 
    func(2.1f); // converts 2.1 to int as 'optional' parameter 
    func<float>(3.3f); // Fine, prints '0' 
    func(); // gcc OK, fails to compile with clang-3.5 
} 

çalışır

Ve çıkarır:

$ ./a.out 
1 
2 
0 
0 

Ama

test_variadic.cpp:15:2: error: no matching function for call to 'func' 
    func(); 
    ^~~~ 
test_variadic.cpp:5:6: note: candidate function template not viable: requires at least argument 'args', but no arguments were provided 
void func(Args... args, int optional = 0) 
    ^

Clang en azından uyardı, clang-3.5 ile derlemeye başarısız olursa bir floattan int'ye dolaylı dönüşüm Güzel, bunu, float parametresini şablon paketine koyan func<float>'u arayarak düzeltebiliriz. Yani, func()'u açıklarsam, iyi derler.

Standart olarak, değişkenlik şablon paketinin parametre-bildirme-sonundaki son şey olması gerektiğini açıkça belirten bir şey bulamıyorum, sadece sonuç çıkarılmamış bir bağlam haline gelir.

Karmaşıklığım, mükemmel bir şekilde kabul edildiğinde, clang neden func()'u sevmiyor. El ile func(int optional = 4) { cout << optional << endl; } tanımlayabilir ve her şey gayet iyi (ancak bunun yerine şablon işlevinin Ben doğru clang ve gcc hem uzman func() olsun int geçerken. Bu aslında kaplıdır func()?

+3

İşte (http://coliru.stacked-crooked.com/a/6d2184a139335a5b) –

+0

[clang 3.5 için çalışır] Ben hangi sürümü olduğunu '$ clang kullanılarak version Ubuntu Target (LLVM üzerinde 3.5 tabanlı) çınlama sürümü 3.5-1ubuntu1 (gövde): x86_64-pc-linux-gnu ' ve komut 'clang ++ -std = c + +11 -O2 -Wall -pedantic test_variadic.cpp' – ilektron

+1

İlginç. Aynı komut satırı, ancak "Ubuntu clang sürüm 3.5.0-svn217640-1 ~ exp1 (dalları/release_35) (LLVM 3.5.0 tabanlı)" ile sadece uyarı ile derler. –

cevap

3

kullanımını kısıtlayan çınlama zorlayıcı özellikte nedir .

aksi şablon argümanlar boş sekansına çıkarılabilir olacak çıkarılmış olup bir arka şablon parametre paketi (14.5.3)

: hafif [temp.arg.explicit]/3 yanlış tarafından

Şablon parametre paketi, func<float>(3.3f) dışındaki tüm çağrılar için boş pakete yönlendiriliyor ve sonuç olarak geçerliydi, yani hepsi de geçerli (ve Clang onları iyi as of 3.5 derler). Biz şimdi

template <typename... Args, typename=void> 
void func(Args... args, int optional = 0) 

için şablonun beyanı ayarlamak kez


Ancak derleyiciler artık uyan değil, yukarıda sözü edilen tırnak (Args olarak sondaki değildir) geçerli değildir ve [temp.deduct.call]/1 yerine geçerlidir:

Bir işlev parametresi paketi, çıkarılmayan bir bağlamda ( (14.8.2.5)) görüntülendiğinde, bu parametre paketinin türü nedir? r çıkarım.

(Yani bu bir kesinti hatası vermelidir.)

+0

http://llvm.org/bugs/enter_bug.cgi?product=clang – ismail

+0

@ilektron adresinden bir clang hatası almayı düşünür müsünüz [buradaki tartışma nedeniyle bu cevabı düzenledim ] (https://llvm.org/bugs/show_bug.cgi?id=21774). – Columbo