2014-05-22 40 views
1

是否有機會編寫元編程功能,但不能擴展編譯中的所有參數?只是想要一些參數作爲運行時參數和一些編譯。因爲我知道其中一些將在1..10的範圍內,但另一個未知(將在運行時知道)。編譯時在C++元編程中使用運行時參數(變量)

允許使用標準的元編程例子:

unsigned int factorial(unsigned int n) { 
    return n == 0 ? 1 : n * factorial(n - 1); 
} 
template <int n> 
struct factorial { 
    enum { value = n * factorial<n - 1>::value }; 
}; 

template <> 
struct factorial<0> { 
    enum { value = 1 }; 
}; 

// Usage examples: 
// factorial<0>::value would yield 1; 
// factorial<4>::value would yield 24. 

而下面是我的情況:

unsigned int cutom_imagined_function(unsigned int n, unsigned int runtime_param /* this will be given at runtime */) { 
    return n == 0 ? 1 : (n + runtime_param) * cutom_imagined_function(n - 1); 
} 

我如何轉換上面元編程?並運行此假設如下(或類似的東西):

// int variable; 
// variable = get_var_from_user(); 
// cutom_imagined_function<4>::value(variable) 
+1

你的例子沒有意義。當factorial是一個只有一個參數的概念時,我該如何描述如何實現'factorial <4>(variable)'? –

+0

@MooingDuck這只是一個例子......編輯。更好? – nosbor

+0

@awesomeyi不能?你爲什麼想讓編譯器確定運行時間的東西? – nosbor

回答

4

您可以使用相同的方法:常量表達式成爲模板參數,一切沒有按「T:

template <unsigned int N> 
struct cutom_imagined 
{ 
    static unsigned int function(unsigned int r) 
    { 
     return (N + r) * cutom_imagined<N - 1>::function(r); 
    } 
}; 

template <> 
struct cutom_imagined<0> 
{ 
    static unsigned int function(unsigned int) { return 1; } 
}; 

用法:

unsigned int result = cutom_imagined<N>::function(get_input()); 
+0

這裏所有的工作都是在運行時完成的,對吧?這仍然是元編程嗎? – unicorn2

+0

@ unicorn2:只有運行時工作在運行時完成。編譯時的東西是在編譯時完成的。 –

+0

你能否詳細說明一下。在nosbor的例子中,Factorial的結果被編譯爲結果值。 例如 int y =因子<6> ::值;看起來像:int y = 720;在.asm中的權利? – unicorn2

3

假設你的意思是這樣的:

unsigned int cutom_imagined_function(
    unsigned int n, 
    unsigned int runtime_param) 
{ 
    return n == 0 ? 1 : (n+runtime_param)*custom_imagined_function(n-1, runtime_param); 
} 

這裏的一般概念,我覺得你描述。這其實很簡單。使函數本身爲模板。

template<unsigned int in> 
unsigned int custom_imagined_function(unsigned int runtime_param) { 
    return (n+runtime_param)*custom_imagined_function<n-1>(runtime_param); 
} 
template<> 
unsigned int custom_imagined_function<0>(unsigned int runtime_param) { 
    return 1; 
} 

int main() { 
    int variable; 
    std::cin >> variable; 
    unsigned int result = custom_imagined_function<4>(variable); 
} 

或者,您可以使用稍微更詳細的std::integral_constant

unsigned int custom_imagined_function(
    std::integral_constant<unsigned int,0>, 
    unsigned int runtime_param) 
{ 
    return 1; 
} 
template<unsigned int in> 
unsigned int custom_imagined_function(
    std::integral_constant<unsigned int,n>, 
    unsigned int runtime_param) 
{ 
    std::integral_constant<unsigned int,n-1> less; 
    return (n+runtime_param) * custom_imagined_function(less, runtime_param); 
} 

int main() { 
    std::integral_constant<unsigned int,4> four; 
    int variable; 
    std::cin >> variable; 
    unsigned int result = custom_imagined_function(four, variable); 
} 

此外,現在我們已經constexpr(在一些編譯器反正),該factorial容易簡化爲:

constexpr unsigned int factorial(unsigned int n) { 
    return n==0?1:n*factorial(n-1); 
} 
+0

好吧,這是一個解決方案,但我想它不會擴展爲原始因子。這是一個簡單的模板,而不是元編程。 – nosbor

+0

@nosbor:「擴展」是什麼意思?你的意思是去掉遞歸併利用'n'在編譯時已知的事實?它已經做到了,它看起來不像它。 –

+0

@dyp:哦,詛咒,他們都這樣做。謝謝 –