Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 生成实例化具有不同参数的函数模板的代码_C++_Templates_C Preprocessor_C++14_Template Instantiation - Fatal编程技术网

C++ 生成实例化具有不同参数的函数模板的代码

C++ 生成实例化具有不同参数的函数模板的代码,c++,templates,c-preprocessor,c++14,template-instantiation,C++,Templates,C Preprocessor,C++14,Template Instantiation,给定以下代码: #include <iostream> template <int X, int Y> int foo(int v) // dummy parameter { return v * X + v / Y; // dummy calculation } int main() { // x, y, v are only known at runtime int x = 4; int y = 6; int v = 3;

给定以下代码:

#include <iostream>

template <int X, int Y>
int foo(int v) // dummy parameter
{
    return v * X + v / Y; // dummy calculation
}

int main()
{
    // x, y, v are only known at runtime
    int x = 4;
    int y = 6;
    int v = 3;

    int result = 0;

    if (x == 1 && y == 1) result = foo<1, 1>(v);
    if (x == 1 && y == 3) result = foo<1, 3>(v);
    if (x == 5 && y == 1) result = foo<5, 1>(v);
    if (x == 4 && y == 6) result = foo<4, 6>(v);
    if (x == 8 && y == 4) result = foo<8, 4>(v);
    // ...

    std::cout << result << std::endl;
}
#包括
模板
int foo(int v)//伪参数
{
返回v*X+v/Y;//伪计算
}
int main()
{
//x、y、v仅在运行时已知
int x=4;
int y=6;
int v=3;
int结果=0;
如果(x==1&&y==1)结果=foo(v);
如果(x==1&&y==3)结果=foo(v);
如果(x==5&&y==1)结果=foo(v);
如果(x==4&&y==6)结果=foo(v);
如果(x==8&&y==4)结果=foo(v);
// ...

std::cout为已知的x和y对生成代码和实例很容易,如果这正是您想要的

#define XYLIST \
X(1,1)\
X(1,3)\
X(5,1)\
X(4,6)\
X(8,4)
// etc.

#define X(X1, Y1) \
if (X1 == 1 && Y1 == 1) result = foo<X1, Y1>(v); else

XYLIST
{ throw "failed"; }

#undef X
#定义木匠\
X(1,1)\
X(1,3)\
X(5,1)\
X(4,6)\
X(8,4)
//等等。
#定义X(X1,Y1)\
如果(X1==1&&Y1==1)结果=foo(v);否则
木匠
{抛出“失败”;}
#未定义X

添加了一个“else”,因为不应该有两行相同的代码。最后添加了一个“throw”来完成else级联。

如果这正是您想要的,那么为已知的x和y对生成代码和实例就很容易了

#define XYLIST \
X(1,1)\
X(1,3)\
X(5,1)\
X(4,6)\
X(8,4)
// etc.

#define X(X1, Y1) \
if (X1 == 1 && Y1 == 1) result = foo<X1, Y1>(v); else

XYLIST
{ throw "failed"; }

#undef X
#定义木匠\
X(1,1)\
X(1,3)\
X(5,1)\
X(4,6)\
X(8,4)
//等等。
#定义X(X1,Y1)\
如果(X1==1&&Y1==1)结果=foo(v);否则
木匠
{抛出“失败”;}
#未定义X

添加了一个“else”,因为不应该有两行相同的行。在末尾添加一个“throw”以完成else级联。

您可以将它们转换为常量表达式。如果事先知道incase值

#include <iostream>

template <int X, int Y>
int foo(int v) // dummy parameter
{
    return v * X + v / Y; // dummy calculation
}

int main()
{
    // x, y, v are only known at runtime
    const int x = 4;
    const int y = 6;
    int v = 3;

   int result = 0;

   result = foo<x, y>(v);


    std::cout << result << std::endl;
}
方法2:如果可以传递任何内容,即双数据类型等

模板
T foo(int v,T Y,T Y)//伪参数
{
返回v*X+v/Y;//伪计算
}

您可以将它们转换为常量表达式。如果事先知道incase值

#include <iostream>

template <int X, int Y>
int foo(int v) // dummy parameter
{
    return v * X + v / Y; // dummy calculation
}

int main()
{
    // x, y, v are only known at runtime
    const int x = 4;
    const int y = 6;
    int v = 3;

   int result = 0;

   result = foo<x, y>(v);


    std::cout << result << std::endl;
}
方法2:如果可以传递任何内容,即双数据类型等

模板
T foo(int v,T Y,T Y)//伪参数
{
返回v*X+v/Y;//伪计算
}

这是一个使用递归的版本

#include <iostream>
#include <utility>
#include <stdexcept>

template <int X, int Y>
int foo(int v) // dummy parameter
{
    return v * X + v / Y; // dummy calculation
}

template <std::size_t index = 0>
int foo(int x, int y, int v) {
    constexpr std::pair<int, int> numbers[] = {{1, 1}, {1, 3}, {5, 1}, {4, 6}, {8, 4}};
    if constexpr (index < sizeof numbers / sizeof *numbers) {
        if (numbers[index].first == x && numbers[index].second == y) {
            return foo<numbers[index].first, numbers[index].second>(v);
        }
        return foo<index + 1>(x, y, v);
    } else { //no match
        throw std::runtime_error("No matching pair found");
    }
}

int main() {
    // x, y, v are only known at runtime
    int x = 4;
    int y = 6;
    int v = 3;

    int result = foo(x, y, v);

    std::cout << result << std::endl;
}
#包括
#包括
#包括
模板
int foo(int v)//伪参数
{
返回v*X+v/Y;//伪计算
}
模板
intfoo(intx,inty,intv){
constexpr std::对数[]={{1,1},{1,3},{5,1},{4,6},{8,4};
if constepr(索引这是一个使用递归的版本

#include <iostream>
#include <utility>
#include <stdexcept>

template <int X, int Y>
int foo(int v) // dummy parameter
{
    return v * X + v / Y; // dummy calculation
}

template <std::size_t index = 0>
int foo(int x, int y, int v) {
    constexpr std::pair<int, int> numbers[] = {{1, 1}, {1, 3}, {5, 1}, {4, 6}, {8, 4}};
    if constexpr (index < sizeof numbers / sizeof *numbers) {
        if (numbers[index].first == x && numbers[index].second == y) {
            return foo<numbers[index].first, numbers[index].second>(v);
        }
        return foo<index + 1>(x, y, v);
    } else { //no match
        throw std::runtime_error("No matching pair found");
    }
}

int main() {
    // x, y, v are only known at runtime
    int x = 4;
    int y = 6;
    int v = 3;

    int result = foo(x, y, v);

    std::cout << result << std::endl;
}
#包括
#包括
#包括
模板
int foo(int v)//伪参数
{
返回v*X+v/Y;//伪计算
}
模板
intfoo(intx,inty,intv){
constexpr std::对数[]={{1,1},{1,3},{5,1},{4,6},{8,4};
if constepr(索引std::cout为什么不使用可变模板参数列表,由成对的想要的组合组成?@user0042:我不知道这是可能的。但是避免预处理器的解决方案当然可以;-,可能是重复。为什么不使用可变模板参数列表,由成对的想要的组合组成?@user0042:我不知道这是可能的。但避免预处理器的解决方案当然可以。;-,可能是重复。谢谢,但我知道在上述情况下,只需在运行时传递每个值的整数参数。;-)这只是一个极小的示例,是编译时知道一些参数的问题的简化版本me有助于提高性能(深度学习库中conv层的LIBEGEN矩阵大小和im2col实现)。为什么不建议对相同的数据类型使用模板?非类型模板很有用。谢谢,但我知道在上述情况下,每个值只需在运行时传递整数参数即可。;-)这只是一个最小的示例,是一个问题的简化版本,在编译时了解一些参数对e性能(深度学习库中conv层的LIBEGEN矩阵大小和im2col实现)。为什么不建议对相同的数据类型使用模板?非类型模板很有用。谢谢!我知道你的解决方案。:)谢谢!我知道你的解决方案。:)很好,我认为从C++14开始,你应该能够使
foo
constepr,因为
抛出
应该只在出现错误时使用,然后你就会出错。很好,我认为从C++14开始u应该能够使
foo
constexpr,因为
throw
应该只在出现错误时使用,然后您就得到了一个错误。