2013-07-15 17 views
6

uygula:biz <code>constexpr</code> olsun C++ 11 yılında derleme zamanı constexpr

constexpr int foo (int x) { 
    return x + 1; 
} 

o x bir derleme zamanı hatası dinamik bir değere sahip foo ait çağırmaları yapmak mümkün mü? Yani, bir foo oluşturmak istiyorum, böylece yalnızca constexpr bağımsız değişkenleri iletilebilir.

+1

Her zaman bir işlev şablonuna dönüştürebilirsiniz: 'template int foo() {return x + 1; } ' –

+1

' Constexpr', burada yanıtlarda göreceğiniz tüm sözdizimsel çözümlere karşı koymak için kısmen çağrıldığını unutmayın. – rubenvb

+0

'#define foo (N) foo ()' Bana uygun görünüyor. –

cevap

8

bir üst-işlevin ile değiştirin:

template <int x> struct foo { static constexpr int value = x + 1; }; 

Kullanımı:

foo<12>::value 
+0

Veya daha iyisi, bir 'işleç()' ver, böylece bir işlev çağrısına benziyor. – rubenvb

+0

@rubenvb: Daha da iyisi, bir değişken şablonu kullanın: 'template int bar = foo :: value;'. Kullanımı: Bar <12> '. C++ 14'te mevcut. –

+0

Oh ....... Kewl. – rubenvb

0

Bu örnekte daha Infos için

#include<iostream> 

constexpr int foo(int x) { 
     return x+1; 
} 

int main() { 
     // Works since its static 
     std::cout << foo(2) << std::endl; 
     static_assert(foo(2) || foo(2) == 0, "Not Static"); 

     // Throws an compile error 
     int in = 3; 
     std::cout << foo(in) << std::endl; 
     static_assert(foo(in) || foo(in) == 0, "Not Static"); 
} 

gösterildiği gibi ben static_assert kullanırsınız: http://en.cppreference.com/w/cpp/language/static_assert

+0

"Constexpr" ile bir derleyici ATM'm yok, fakat bu fikir 'static_assert' doğrudan 'foo' içine koymayacak mı? Örneğin. constexpr int foo (int x) {statik_assert (x == x, "Statik Değil"); x + 1 döndürün; } ' –

+1

@ThomasEding. Yapabilirdiniz ama daha sonra çalışma zamanı değerlendirilen işlevle aynı işlevi kullanmanın esnekliğini kaybedersiniz. Statik_assert 'derleme zamanında kontrol edildiğinden, çalışma zamanını da etkilemez. –

2

Ne yazık ki, en önemsiz olanı bile olan constexpr işlevinin kesinlikle gerekli olmadıkça derleyici tarafından değerlendirileceğinin bir yolu yoktur. Yani, derleme zamanında değerinin gerekli olduğu bir yerde görünmediği sürece, örn. bir şablonda. derleme sırasında değerlendirme yapmak için derleyici zorlamak için, aşağıdakileri yapabilirsiniz: o zaman

constexpr int foo_implementation (int x) { 
    return x + 1; 
} 

#define foo(x) std::integral_constant<int, foo_implementation(x)>::value 

ve her zamanki

olarak kodunuzda foo kullanmak
int f = foo(123); 

bu yaklaşımının iyi olduğunu o derleme zamanı değerlendirme garanti ve foo bir çalışma zamanı değişken geçmek eğer bir derleme hatası alırsınız:

int a = 2; 
int f = foo(a); /* Error: invalid template argument for 'std::integral_constant', 
        expected compile-time constant expression */ 

o kadar iyi bir şey, bir makro gerektirmesidir, ancak hem garantili derleme zamanı değerlendirmesi hem de güzel kodlar istiyorsanız, bu durum kaçınılmaz görünmektedir. (Olsa da yanıltılmayı çok isterim!)

İlgili konular