Garip dil sorunu CWG 1581 :
Madde 15 [özel], özel üye işlevlerinin yalnızca odr kullanıldıklarında dolaylı olarak tanımlandıklarını açıkça göstermektedir. Bu, değerlendirilmemiş bağlamlarda sabit ifadeler için bir sorun yaratır:
struct duration {
constexpr duration() {}
constexpr operator int() const { return 0; }
};
// duration d = duration(); // #1
int n = sizeof(short{duration(duration())});
Buradaki sorun constexpr duration::duration(duration&&)
, bu programda örtülü olarak tanımlanmasına izin verilmemesidir , bu nedenle başlatıcı listesindeki ifade sabit bir ifade değildir (tanımlanmamış bir constexpr işlevini çağırdığı için), bu nedenle hazır başlatıcı daraltma dönüşümü içerir , böylece program kötü biçimlendirilmiş.
1 numaralı satırı kaldırırsak, move yapıcısı dolaylı olarak tanımlanır ve program geçerlidir. Uzaktan bu ürkütücü eylem son derece talihsiz. Uygulamalar bu noktada birbirinden ayrılmaktadır.
Sorun açıklamasının geri kalanını okuyabilirsiniz.
Bu sorun için bir çözüm , 2017'de Albuquerque'deki P0859'da (C ++ 17 gönderildikten sonra) kabul edildi. Bu sorun, bir engelleyici olduğunu hem olması mümkün constexpr std::swap
(giderilmiş P0879 ) ve constexpr std::invoke
(giderilmiş P1065 20 C ++, her ikisi de, aynı zamanda CWG1581 örnekler vardır).
Burada anlaşılması en kolay örnek, bence, P1065'te belirtilen LLVM hata raporunun kodudur:
template<typename T>
int f(T x)
{
return x.get();
}
template<typename T>
constexpr int g(T x)
{
return x.get();
}
int main() {
// O.K. The body of `f' is not required.
decltype(f(0)) a;
// Seems to instantiate the body of `g'
// and results in an error.
decltype(g(0)) b;
return 0;
}
CWG1581 ilgili olduğunu ne zaman kullanıldığında sadece tanımlanmış olduğunuzu constexpr üye fonksiyonları tanımlanır ve çözünürlük olmasını sağlar. P0859 sonra yukarıdaki (tipini iyi oluşturulur b
olan int
).
Yana std::swap
ve std::invoke
her iki üye fonksiyonları için (eski içinde hareket inşaat / atama ve çağrı operatörü / ikincisinde vekil çağrıları), ikisi de bu sorunun çözümü bağlıydı kontrol dayanmak zorundadır.