Ben oynamalar autoiçinde std::pair. Aşağıdaki kodda, fonksiyonun bir template parametresine bağlı olan bir tür fdöndürmesi beklenir std::pair.
Çalışan bir örnek:
ÖRNEK 1
template <unsigned S>
auto f()
{
if constexpr (S == 1)
return std::pair{1, 2}; // pair of ints
else if constexpr (S == 2)
return std::pair{1.0, 2.0}; // pair of doubles
else
return std::pair{0.0f, 0.0f}; // pair of floats
}
Bu, gcc 9.2, gcc 10.0, clang 9.0 ve clang 10.0 ile çalışır.
Sonra, std::pairnetlik nedenleriyle açıkça bir dönüş türü yazmak istedim :
ÖRNEK 2
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return {1, 2};
/* ... */
}
Hem gcc 9.2 / 10.0 hem de clang 9.0 / 10.0 bunu derleyemedi.
gcc 9.2
error: invalid use of 'auto'
error: template argument 1 is invalid // first argument (auto) of std::pair
error: template argument 2 is invalid // second argument (auto) of std::pair
error: cannot convert '<brace-enclosed initializer list>' to 'int' in return
Son hata mesajından, gcc 9.2 std::pair<auto, auto>bunun bir olduğuna inanıyor gibi görünüyor int. Bu nasıl açıklanabilir?
gcc 10.0
error: returning initializer list
Bu hata anlaşılabilir, ancak std::pairkurucunun çağrılmasını bekledim, yoksa burada eksik olduğum bir şey var mı?
clang 9.0 ve 10.0
'auto' not allowed in template argument
excess elements in scalar initializer
no matching function for call to 'f'
Tamam, clang bunların hiçbirini sevmiyor. İkinci hata mesajından, clang da dönüş türünün olduğuna inanıyor gibi görünüyor int.
Son olarak, gcc 10.0 ile derlenen hatayı düzeltmek için, std::pairaçıkça dönmeye karar verdim :
ÖRNEK 3
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return std::pair{1, 2};
/* ... */
}
clang 9.0 ve 10.0
Öncekiyle aynı, ancak ek olarak:
no viable conversion from returned value of type 'std::pair<int, int>' to function return type 'int'
Burada clang hala geri döndüğümüzü düşünüyor int?
gcc 9.2
Öncekinin aynısı.
gcc 10.0
İşe yarıyor!
Bazı özelliklerin hala uygulanması gerekiyor, ya da yukarıda açıklanan durumlardan birinde, doğru ve diğeri yanlış olan bir derleyici var mı? Bence, örnek 2 işe yaramalı. Yoksa değil mi?