Ben oynamalar auto
içinde std::pair
. Aşağıdaki kodda, fonksiyonun bir template parametresine bağlı olan bir tür f
dö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::pair
netlik 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::pair
kurucunun ç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::pair
açı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?