2017-11-14 132 views
12

Bugün clang'ın C++ 17 destek sayfasını okuyordum. Garip bir şey fark ettim. o bir anahtar üzerinden aktif hale gerektiğinden uyumlu argümanlar (P0522R0) için özellik Eşleştirme şablon şablon parametreleri, kısmi işaretlenir. Onların not says:P0522R0 kırma kodu nasıl?

bir Kusur Raporuna çözünürlüğü olmasına rağmen, bu özellik Clang 4'te -frelaxed-template-şablon-args tüm dil sürümlerinde varsayılan olarak devre dışıdır ve bayrak ile açıkça etkinleştirilebilir Standarttaki değişiklik, şablon kısmi sıralaması için uygun bir değişiklikten yoksun olup, makul ve önceden geçerli olan kod için belirsizlik hatalarıyla sonuçlanır. Bu sayının yakında düzeltilmesi bekleniyor.

Ne yapılar sonları tür bu özellik aktif hale getirildiğinde? Neden kodu ve nasıl bozabilir? foo iki tek bir şablon parametresi ile bir şablon alır ve çünkü, kusur çözünürlük olmadan

template<template<typename> typename> 
struct Foo {}; 

template<typename, typename = void> 
struct Bar {}; 

Foo<Bar> unused; 

, unused kötü kurulacağını:

cevap

12

Böyle bir kod olabilir. Buna güveniyorsanız (belki de SFINAE için):

Ardından çağrı başarısız olur! Sorun, kısmi sıralamada karşılık gelen bir değişiklik olmamasıdır ve bu nedenle her iki aday fonksiyon aynı canlılığa sahiptir ve çağrı belirsizdir. Bazı kod

template<class> struct Foo; 

template<template<class> class X, class T> 
struct Foo<X<T>> { /* ... */ }; 

template<template<class, class> class X, class T, class U> 
struct Foo<X<T, U>> { /* ... */ }; 

// etc., etc. 

Foo<std::vector<int>> şimdi uygun bir kısmi sıralama düzeltme olmadan kötü oluşur .: kısmi uzmanlık seti ile şablon argümanları incelemek için örneğin istediğinde

+0

Ah anlıyorum. Örneğinizde, 'foo'nun ikinci versiyonunun alınmasını beklerdim. –

+6

@Guillaume Evet, çünkü daha iyi bir eşleşme. Ama standart kendim ben SO bu konuda bir kaç soru gördüğüm – Rakete1111

+3

:(kısmi sıralamada metin var, hatta onun içine çalışmaz. Ben en yaygın senaryo birisi bir kap tamamlıyor olduğunu düşünüyorum , özellikle 'std :: vector' ve bunun da bir allocator olduğunu unutuyorlar, bu yüzden bu gibi bir kodla sonuçlanırsınız (https://wandbox.org/permlink/lYy8DNiF61ZH4Fmp) – AndyG

3

Bir daha yaygın senaryodur.