简体   繁体   English

在编译时在C ++元编程中使用运行时参数(变量)

[英]Using a runtime parameter (variable) in C++ metaprogramming at compile-time

Is there opportunity to make metaprogramming function but not expand all parameters in compilation? 是否有机会使元编程功能但不扩展编译中的所有参数? Just want to have some parameters as the runtime parameters and some compiles. 只想拥有一些参数作为运行时参数并进行一些编译。 Because I know that some of them will be in range of 1..10 but the other are unkown (will be known at runtime). 因为我知道其中一些会在1..10范围内,而另一些则是未知的(将在运行时知道)。

Lets use standard metaprogramming example: 让我们使用标准元编程示例:

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.

And below is my case: 下面是我的情况:

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); 
}

how can I convert above to metaprogramming? 如何将以上转换为元编程? And run this let's say as below (or something similar): 并运行如下所示(或类似内容):

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

You can use the same approach: Constant expressions become template parameters, everything else doesn'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; }
};

Usage: 用法:

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

Assuming you meant this: 假设您的意思是:

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); 
}

here's the general concept I think you're describing. 这是我认为您正在描述的一般概念。 It's actually pretty straightforward. 实际上非常简单。 Make the function itself a template. 使函数本身成为模板。

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);
}

Alternatively, you can use the slightly more verbose std::integral_constant . 另外,您可以使用稍微更详细的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);
}

Additionally, now that we have constexpr (in some compilers anyway), the factorial is easily simplified: 此外,现在有了constexpr (无论如何在某些编译器中), factorial容易简化:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM