C++ 14'te constexpr işlevleriyle deneme yapıyorum. beklendiği gibi faktöryel eserlerini hesaplar aşağıdaki kod,: clang şöyle derlenirC++ 14: üçlü ifadelerle Constexpr'ten çıkarılan (otomatik) dönüş türleri
template <typename T>
constexpr auto fact(T a) {
if(a==1)
return 1;
return a*fact(a-1);
}
int main(void) {
static_assert(fact(3)==6, "fact doesn't work");
}
:
> clang++ --version
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
> clang++ -std=c++14 constexpr.cpp
Ancak, üçlü ?
operatörü kullanmak fact
tanımını değiştirdiğinizde:
template <typename T>
constexpr auto fact(T a) {
return a==1 ? 1 : a*fact(a-1);
}
aşağıdaki derleyici hatası alıyorum Açıkça dönüş tipi T bildiririseniz Sorun şablon parametresi çıkarmak durumunda
template <typename T>
constexpr T fact(T a) {
return a==1 ? 1 : a*fact(a-1);
}
(yerine dönüş türü anlamak için otomatik kullanarak) sabitlenir
> clang++ -std=c++14 constexpr.cpp
constexpr.cpp:12:31: fatal error: recursive template instantiation exceeded maximum depth of
256
return a==T(1) ? T(1) : a*fact(a-1);
... snip ...
constexpr.cpp:16:19: note: in instantiation of function template specialization 'fact<int>'
requested here
static_assert(fact(3)==6, "fact doesn't work");
, desen (üçlü versiyonu tekrarlanır başarısız olur ve if
versiyonu çalışır) bu oysa
// this works just fine
constexpr auto fact(int a) {
if(a==1)
return 1;
return a*fact(a-1);
}
constexpr auto fact(int a) {
return a==1 ? 1 : a*fact(a-1);
}
başarısız Aşağıdaki hata ile
> clang++ -std=c++14 constexpr.cpp
constexpr.cpp:16:25: error: function 'fact' with deduced return type cannot be used before it
is defined
return a==1 ? 1 : a*fact(a-1);
^
constexpr.cpp:15:16: note: 'fact' declared here
constexpr auto fact(int a) {
^
constexpr.cpp:20:26: error: invalid operands to binary expression ('void' and 'int')
static_assert(fact(3)==6, "fact doesn't work");
~~~~~~~^ ~
2 errors generated.
Burada neler oluyor?
sürümü iki dönüş ifadeleri varsa ile. Derleyici kullanımı/standardı bir tür temkinli boşalma belirtiyor mu, sadece bir == 1 olduğunda if bloğunda dönüş ifadesini dikkate alıyor? Aksi takdirde, her iki versiyonda da aynı problem olurdu. – bcumming
Teşekkür @Praetorian. Kendime bakabilirim (bir dil avukatım olmasa da). – bcumming
@Praetorian Daha önce iddia ettiğiniz şeylerin tam tersi değil. Her bir getiri beyanı için getiri türü çıkarılır, ancak * herhangi bir getiri beyanı için çıkarıldıktan sonra, getiri türü bilinir ve daha sonraki getiri beyannamelerinin indirilmesinin bir parçası olarak kullanılabilir. 'Template 'örneğiyle başarısız olmanızın nedeni," aslında "türünün dönüş türünün bilinmesi gerçeği" aslında "dönüş türüyle ilgili hiçbir şey söylemez, ancak' ' aslında OP kodunda "aslında " olarak adlandırılır. . –
hvd