C++ 可变函数
我试图编写一个类来表示一个张量C++ 可变函数,c++,c++11,variadic-templates,variadic-functions,variadic,C++,C++11,Variadic Templates,Variadic Functions,Variadic,我试图编写一个类来表示一个张量张量,并希望为二维张量提供语法张量(I,j),为三维张量提供语法张量(I,j,k),以此类推 我想知道的是,是否有一种C++类型的安全方法来声明这样的张量:操作程序()(int,int,…)< /> >接受任何数量的 int 参数(除了C风格与宏 VAXSTATEVAXEDING/)以及如何在函数中使用这些参数。 谢谢您的时间。好吧,您可以随时使用普通的参数包;但强制编译失败,除非所有参数都是ints: #include <utility> #inclu
张量
,并希望为二维张量提供语法张量(I,j)
,为三维张量提供语法张量(I,j,k)
,以此类推
我想知道的是,是否有一种C++类型的安全方法来声明这样的<代码>张量:操作程序()(int,int,…)< /> >接受任何数量的<代码> int <代码>参数(除了C风格与宏<代码> VAXSTATEVAXEDING/<代码>)以及如何在函数中使用这些参数。
谢谢您的时间。好吧,您可以随时使用普通的参数包;但强制编译失败,除非所有参数都是
int
s:
#include <utility>
#include <type_traits>
class foo {
public:
template<typename ...Args,
typename=std::void_t<std::enable_if_t
<std::is_same_v<Args, int>>...>>
void operator()(Args ...args)
{
}
};
void bar()
{
foo bar;
bar(4, 2);
}
或
请注意,这不会编译:
unsigned baz=2;
bar(4, baz);
如果需要接受无符号的值,请相应地在模板上添加符号
请注意,模板不需要使用转发引用,因为唯一可接受的参数是纯
int
s。在模板函数中,您现在有了一个garden variety参数包,您可以使用与使用任何其他参数包相同的方法来使用它。嗯,您可以始终使用普通参数包;但强制编译失败,除非所有参数都是int
s:
#include <utility>
#include <type_traits>
class foo {
public:
template<typename ...Args,
typename=std::void_t<std::enable_if_t
<std::is_same_v<Args, int>>...>>
void operator()(Args ...args)
{
}
};
void bar()
{
foo bar;
bar(4, 2);
}
或
请注意,这不会编译:
unsigned baz=2;
bar(4, baz);
如果需要接受无符号的值,请相应地在模板上添加符号
请注意,模板不需要使用转发引用,因为唯一可接受的参数是纯
int
s。在模板函数中,您现在有了一个garden variety参数包,您可以使用与使用任何其他参数包相同的方法。也可以接受无符号int
和其他可转换为int
的类型,并且如果您可以接受上限(63,在下面的示例中)对于整数参数的个数,我建议如下
因此,您可以开发一个打字机
template <typename T, std::size_t>
using typer = T;
继承自proOp
,Tensor
成为
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
结构张量:公共proOp
{
使用proOp::operator();
};
下面是一个完整的工作示例
#include <utility>
template <typename T, std::size_t>
using typer = T;
template <typename T, std::size_t N = 64U,
typename = std::make_index_sequence<N>>
struct proOp;
template <typename T, std::size_t N, std::size_t... Is>
struct proOp<T, N, std::index_sequence<Is...>> : public proOp<T, N-1U>
{
using proOp<T, N-1U>::operator();
void operator() (typer<T, Is>... ts)
{ }
};
template <typename T>
struct proOp<T, 0U, std::index_sequence<>>
{
void operator() ()
{ }
};
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
struct Tensor
{
// recursive case
template <typename ... Ts>
void operator() (int i0, Ts ... is)
{
// do something with i0
this->operator()(is...); // recursion
}
void operator() ()
{ }
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
#包括
样板
使用typer=T;
样板
结构工程;
样板
结构项目:公共项目
{
使用proOp::operator();
void运算符()(打字机…ts)
{ }
};
样板
结构工程
{
void运算符()()
{ }
};
结构张量:公共proOp
{
使用proOp::operator();
};
int main()
{
张量t;
t(1,2,3);
t(1,2,3,4U);//也接受未签名
//t(1,“2”);//错误
}
要同时接受无符号int
和其他可转换为int
的类型,并且如果您可以接受整数参数数量的上限(在下面的示例中为63),我建议遵循
因此,您可以开发一个打字机
template <typename T, std::size_t>
using typer = T;
继承自proOp
,Tensor
成为
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
结构张量:公共proOp
{
使用proOp::operator();
};
下面是一个完整的工作示例
#include <utility>
template <typename T, std::size_t>
using typer = T;
template <typename T, std::size_t N = 64U,
typename = std::make_index_sequence<N>>
struct proOp;
template <typename T, std::size_t N, std::size_t... Is>
struct proOp<T, N, std::index_sequence<Is...>> : public proOp<T, N-1U>
{
using proOp<T, N-1U>::operator();
void operator() (typer<T, Is>... ts)
{ }
};
template <typename T>
struct proOp<T, 0U, std::index_sequence<>>
{
void operator() ()
{ }
};
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
struct Tensor
{
// recursive case
template <typename ... Ts>
void operator() (int i0, Ts ... is)
{
// do something with i0
this->operator()(is...); // recursion
}
void operator() ()
{ }
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
#包括
样板
使用typer=T;
样板
结构工程;
样板
结构项目:公共项目
{
使用proOp::operator();
void运算符()(打字机…ts)
{ }
};
样板
结构工程
{
void运算符()()
{ }
};
结构张量:公共proOp
{
使用proOp::operator();
};
int main()
{
张量t;
t(1,2,3);
t(1,2,3,4U);//也接受未签名
//t(1,“2”);//错误
}
另一种方法是使运算符()递归,并在每次递归中使用第一个参数
// recursive case
template <typename ... Ts>
void operator() (int i0, Ts ... is)
{
// do something with i0
this->operator()(is...); // recursion
}
void operator() ()
{ }
//递归大小写
样板
void运算符()(int i0,Ts…is)
{
//用i0做点什么
this->operator()(is…;//递归
}
void运算符()()
{ }
下面是一个完整的工作示例
#include <utility>
template <typename T, std::size_t>
using typer = T;
template <typename T, std::size_t N = 64U,
typename = std::make_index_sequence<N>>
struct proOp;
template <typename T, std::size_t N, std::size_t... Is>
struct proOp<T, N, std::index_sequence<Is...>> : public proOp<T, N-1U>
{
using proOp<T, N-1U>::operator();
void operator() (typer<T, Is>... ts)
{ }
};
template <typename T>
struct proOp<T, 0U, std::index_sequence<>>
{
void operator() ()
{ }
};
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
struct Tensor
{
// recursive case
template <typename ... Ts>
void operator() (int i0, Ts ... is)
{
// do something with i0
this->operator()(is...); // recursion
}
void operator() ()
{ }
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
结构张量
{
//递归案例
样板
void运算符()(int i0,Ts…is)
{
//用i0做点什么
this->operator()(is…;//递归
}
void运算符()()
{ }
};
int main()
{
张量t;
t(1,2,3);
t(1,2,3,4U);//也接受未签名
//t(1,“2”);//错误
}
另一种方法是使运算符()递归,并在每次递归中使用第一个参数
// recursive case
template <typename ... Ts>
void operator() (int i0, Ts ... is)
{
// do something with i0
this->operator()(is...); // recursion
}
void operator() ()
{ }
//递归大小写
样板
void运算符()(int i0,Ts…is)
{
//用i0做点什么
this->operator()(is…;//递归
}
void运算符()()
{ }
下面是一个完整的工作示例
#include <utility>
template <typename T, std::size_t>
using typer = T;
template <typename T, std::size_t N = 64U,
typename = std::make_index_sequence<N>>
struct proOp;
template <typename T, std::size_t N, std::size_t... Is>
struct proOp<T, N, std::index_sequence<Is...>> : public proOp<T, N-1U>
{
using proOp<T, N-1U>::operator();
void operator() (typer<T, Is>... ts)
{ }
};
template <typename T>
struct proOp<T, 0U, std::index_sequence<>>
{
void operator() ()
{ }
};
struct Tensor : public proOp<int>
{
using proOp<int>::operator();
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
struct Tensor
{
// recursive case
template <typename ... Ts>
void operator() (int i0, Ts ... is)
{
// do something with i0
this->operator()(is...); // recursion
}
void operator() ()
{ }
};
int main()
{
Tensor t;
t(1, 2, 3);
t(1, 2, 3, 4U); // accept also unsigned
//t(1, "two"); // error
}
结构张量
{
//递归案例
样板
void运算符()(int i0,Ts…is)
{
//用i0做点什么
this->operator()(is…;//递归
}
void运算符()()
{ }
};
int main()
{
张量t;
t(1,2,3);
t(1,2,3,4U);//也接受未签名
//t(1,“2”);//错误
}
有一种更简洁的方法可以创建安全的变量函数,而无需使用递归和std::enable\u,如果:
template <typename ...Ints>
void function(int first, Ints... other)
{
int values[] = {first, other...};
for(int value : values)
{
//your code
}
}
模板
无效函数(整数优先,整数…其他)
{
int值[]={first,other…};
for(int值:值)
{
//你的代码
}
}
这种方法也是类型安全的,
函数(1,“2”,3)
不会编译。有一种更简洁的方法来创建安全的变量函数,而不使用递归和std::enable\u,如果:
template <typename ...Ints>
void function(int first, Ints... other)
{
int values[] = {first, other...};
for(int value : values)
{
//your code
}
}
模板
无效函数(整数优先,整数…其他)
{
int值[]={first,other…};
for(int值:值)
{
//你的代码
}
}
这种方式也是类型安全的,
。如果你的是 std::tuple