2016-06-17 17 views
7
Bu yüzden bu soruya cevap oldu

: Define friend function template of class template ve bazı "tuhaf" g davranışı ++ (5.3) ve clang (3.8) bulunan:Dönüş tipi maç

en Aşağıdaki şablonu varsayalım : (- bu derleme giremiyorum, yorum ve niçin çekinmeyin beklendiği gibi)

template<int M> 
struct test { 
private: 
    int value; 

    template<int U, int K> 
    friend test<K> foo (test<U> const t); 
}; 

template <int M, int N = 2 * M> 
test<N> foo (test<M> const t) { 
    test<N> r; 
    r.value = t.value; 
    return r; 
} 

int main(){ 
    test<1> t; 
    foo(t); 
} 

Bu, hem derleyici ile derleme.

Ben şeyler değiştirirseniz:

template<int U, int K> 
friend test<K> foo(test<U> const t); 

template <int M, int N = 2 * M> 
auto foo (test<M> const t) { /* ... */ } 

// or: 

template<int U, int K> 
friend auto foo(test<U> const t); 

template <int M, int N = 2 * M> 
test<N> foo (test<M> const t) { /* ... */ } 
: g ile ++ ancak clang derlemek Bu

template<int U, int K> 
friend auto foo(test<U> const t); 

template <int M, int N = 2 * M> 
auto foo (test<M> const t) { /* ... */ } 

ve ben auto için bir ve belirli bir değere diğeri, örneğin ayarlarsanız

error: 'int test<2>::value' is private

Benim iki ilişkili sorulara

şunlardır:

Hem derleyici söyleyerek kodu reddetmek

  • İlk derleme için hangi derleyici doğrudur (her iki bildirim için de auto)?
  • Neden işlevi tanımlarken auto ve arkadaşlığı bildirirken test<K> kullanmak mümkün değil mi?

Veya bir soru: function sınıf dışındaki tanımlandığında arkadaş işlev bildirimleri için auto ilgili kurallar nelerdir?

cevap

4

[dcl.spec.auto]/13 düşünün:

Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type.

yani arkadaş beyanı auto kullanıyor ve ikinci bildirim yapmıyorsa, eşleşmiyorlar. Diğer bir şekilde core issue 2081 garanti edilmektedir. Son olarak, her ikisi de auto kullanıyorsa, bildirimler gerçekten [temp.over.link]/6 uyarınca eşleşmelidir, bu nedenle Clang bu durumda yanlıştır.