2014-10-27 31 views
12

Bazı şeylerin nasıl çalıştığına dair biraz daha fazla bilgi edinmek için C++ 11 kullanarak bazı oyuncak kodları ile oynuyorum.constexpr işlev parametrelerini şablon argümanları olarak

template <int x, int y> 
class add { 
public: 
    static constexpr int ret = x + y; 
}; 

constexpr int addFunc(const int x, const int y) { 
    return add<x,y>::ret; 
} 

int main() { 
    const int x = 1; 
    const int y = 2; 
    cout << add<x,y>::ret << endl; // Works 
    cout << addFunc(1,2) << endl; // Compiler error 
    return 0; 
} 

Ben GCC 4.8.1 kullanıyorum ve çıkışı:
'x' türü için şablon argüman sabit bir ifade değildir 'int bu sırasında aşağı basitleştiren aşağıdaki sorun rastladı '
'y int 'tam olarak add::ret hesaplamak çalışıyorum iki şekilde arasındaki fark nedir

' türü için şablon argüman sabit bir ifade değildir?' Bu değerlerin ikisi de derleme zamanında mevcut olmalıdır.

+3

'constexpr' işlevlerinin çalışma zamanında çalıştırılabilmesi gerekir. – chris

+1

Şey ... evet. Öyleyse neden bu özellikle derleme zamanında değerlendirilemiyor? – Danny

+6

Detaylandırmak için: 'constexpr' işlevlerinin çalışma zamanında çalıştırılabilmesi gerekir ve 'constexpr' işleviniz derleme zamanı sabiti olmayan herhangi bir değerle çağrıldığında başarısız olur, dolayısıyla' constexpr' işleviniz geçerli değildir . Aradığın şey, constexpr'in sağladığı şey değil, ve C++ başka bir formda da bir şey değil. En yakın olanı 'addFunc'' int x' ve 'int'' şablon parametreleriyle bir şablon işlevi yapmaktır. – hvd

cevap

7

Derleyiciye, addFunc'un bir constexpr olacağını söylersiniz. Ama bu, kendisinin değil, kendisinin de belirlediği parametrelere dayanır. Onları işaretlemek yalnızca onları işlev gövdesinde değiştirmeyeceğiniz anlamına gelir ve bu noktada yaptığınız özel çağrılar bu noktada dikkate alınmaz.

Eğer sadece addFunc için zaman sabitlerini derlemek geçeceğini anlamak derleyici yapabilir bir yolu yoktur: parametrelerini Yap şablon parametreleri kendisi:

template <int x, int y> 
constexpr int addFunc() { 
    return add<x,y>::ret; 
} 

Ardından çağrı

cout << addFunc<1,2>() << endl; 
5

Derleyici, x ve y'nin sabit değerler (ifade) olarak derleme zamanında her zaman kullanılabilir olup olmadığını ve C++ 11/14'ün constexpr işlev parametresini desteklemediğini bilmiyor, dolayısıyla x yolu yok ve y, addFunc'de şablon <> eklemek için parametre olarak kullanılabilir.

7

amacınız değişken şablon oluşturabilir kodu C++ 14 biraz, kısaltmak için sadece ise:

template <int x, int y> 
constexpr int addVar = x + y; 

cout << addVar<5, 6> << endl; // Works with clang 3.5, fails on GCC 4.9.1 

GCC 5 will also support this.

3
olarak

constexpr işlevinin işlev parametreleri, sabit ifadeler değildir. Fonksiyon constexpr dışarısıdır (sabit bir ifadeyle sonuçlanabileceği için), ancak içerdeki hesaplamalar, normal bir işlevde olduğu gibi constexpr gibidir.

Şablon bağımsız değişkenleri, sabit ifadeler gerektirir.

bir koşullu ekspresyonu bir olup: Bunlar kod araya ve böylece derleyici hata ([expr.const]/2, vurgu benim) üretmek olmayan sabit değerler için çok önemli gereksinimleri potansiyel değerlendirildi alt ifade (3.2) olarak aşağıdakilerden birini içermektedir bunun sürece çekirdek sabit ifade [...]:


- bir lvalue-için-rvalue dönüşüm (4.1)

  • önceki bir başlatma ile uçucu olmayan bir const nesne belirtir yekpare veya sıralama tipi bir glvalue uygulanmadığı takdirde, sabit bir ifade ile veya
  • bir glvalue başlatıldı hazır tip constexpr ile tanımlanan bir uçucu olmayan nesne belirtmektedir, ya da bu tür bir nesnenin bir alt nesneye karşılık gelir ya da
  • uçucu olmayan bir geçici nesne belirtir değişmez tipte bir glvalue ömrü bitmemiş, sabit bir ifadesiyle başlatılmış;

şablon argümanları olarak geçmek parametreleri üzerinde lvalue-to-rvalue dönüşüm uygulamaktadır.
İlk madde işareti, işlev parametresinin ne başlangıçta başlatıldığının ne de sabit bir ifade ile başlatıldığının, ikinci ve üçüncü öğelerin de (özellikle, işlev parametrelerinin constexpr bildirilmemesi) olduğu için geçerli değildir.

İlgili konular