Andrew Sutton'ın (gcc'de uygulayan Concepts yazarlarından biri) bu konuda oldukça yardımcı olması için bir yorum buldum , bu yüzden burada tam olarak alıntı yapacağımı düşündüm:
Çok uzun zaman önce, kısıt ifadelerinde (ilkin gerektirdiği ifade) zorunlu-ifadelere (ikincinin gerektirdiği ifadeye) izin verilmedi. Yalnızca kavram tanımlarında görünebilir. Aslında, tam olarak bu iddianın ortaya çıktığı bölümde önerilen şey budur.
Ancak, 2016 yılında bu kısıtlamanın hafifletilmesi için bir teklif vardı [Editörün notu: P0266 ]. Makalenin 4. bölümündeki 4. paragrafın üstü çizili olduğuna dikkat edin. Ve böylece doğar gerektirir gerektirir.
Doğruyu söylemek gerekirse, bu kısıtlamayı hiçbir zaman GCC'de uygulamamıştım, bu yüzden her zaman mümkün olmuştu. Walter'ın bunu keşfetmiş ve faydalı bulmuş olabileceğini düşünüyorum.
Kimse yazmaya karşı duyarlı olmadığımı iki kere gerektirdiğini düşünse de, bunun basitleştirilip basitleştirilemeyeceğini belirlemek için biraz zaman harcadım. Kısa cevap: hayır.
Sorun, bir şablon parametre listesinden sonra sokulması gereken iki dilbilgisi yapısı olmasıdır: çok yaygın olarak bir kısıt ifadesi (gibi P && Q
) ve bazen de sözdizimsel gereksinimler (gibi requires (T a) { ... }
). Buna gereksinim ifadesi denir.
Birincisi kısıtlamayı getirir. İkincisi, gerektirir-ifadesini sunar. Sadece dilbilgisi bu şekilde oluşturulur. Hiç kafa karıştırıcı bulmuyorum.
Bir noktada bunları tek bir çöküşe uğraşmaya çalıştım. Ne yazık ki, bu bazı ciddi zor ayrıştırma sorunlarına yol açar. Kolayca söyleyemezsiniz, örneğin (
bir sonrakinin iç içe geçmiş bir alt ifadeyi veya bir parametre listesini gösterip göstermediğini. Bu sözdizimlerinin mükemmel bir anlamsızlık olduğuna inanmıyorum (tekdüze başlatma sözdiziminin gerekçesine bakın; bu sorun da var).
Yani bir seçim yaparsınız: make, bir ifadeyi (şimdi olduğu gibi) tanıtmayı veya parametreli bir gereksinimler listesi sunmasını gerektirir.
Mevcut yaklaşımı seçtim çünkü çoğu zaman (neredeyse% 100'ünde olduğu gibi), zorunlu ifade dışında bir şey istiyorum. Ve son derece nadir durumlarda, geçici kısıtlamalar için bir gereksinim ifadesi istemiştim, kelimeyi iki kez yazmayı gerçekten umursamıyorum. Şablon için yeterince sağlam bir soyutlama geliştirmediğimin açık bir göstergesi. (Çünkü sahip olsaydım, bir ismi olurdu.)
Ben gerektirir gerektirir-ifade tanıtmak yapmak için seçmiş olabilir. Bu aslında daha kötü, çünkü neredeyse tüm kısıtlamalarınız şöyle görünmeye başlayacaktı:
template<typename T>
requires { requires Eq<T>; }
void f(T a, T b);
Burada, ikinci gereksinime iç içe gereksinim denir; ifadesini değerlendirir (gerektiren ifadenin bloğundaki diğer kod değerlendirilmez). Bunun statükodan çok daha kötü olduğunu düşünüyorum. Şimdi, her yerde iki kez yazma gerektirir.
Daha fazla anahtar kelime de kullanabilirdim. Bu kendi başına bir problem --- ve sadece bisiklet atma değil. Yinelenmeyi önlemek için anahtar kelimeleri yeniden dağıtmanın bir yolu olabilir, ancak bu ciddi düşünceyi vermedim. Ancak bu, sorunun özünü gerçekten değiştirmez.
noexcept(noexcept(...))
.