函数在可变参数模板的实例化期间不可见
Function not visible durring instantiation of variadic templates
我正在尝试创建一个返回数组数组的零填充数组的函数... 以下 优雅地定义 我定义的现代C++多维数组:
template<typename U, std::size_t N, std::size_t... M>
struct myTensor{
using type = std::array<typename myTensor<U, M...>::type, N>;
};
template<typename U, std::size_t N>
struct myTensor<U,N>{
using type = std::array<U, N>;
};
template<typename U, std::size_t... N>
using myTensor_t = typename myTensor<U, N...>::type;
然后,我定义以下模板函数以填充零:
template<typename U, std::size_t N, std::size_t... M>
myTensor_t<U, N, M...> Zero_Tensor(){
myTensor_t<U, N, M...> res;
for(int i=0; i<N; i++)
res[i] = Zero_Tensor<U, M...>();
return res;
};
template<typename U, std::size_t N>
myTensor_t<U, N> Zero_Tensor(){
myTensor_t<U, N> res;
for(int i=0; i<N; i++)
res[i] = U(0);
return res;
};
例如,当我这样做时
class myclass{
myTensor_t<int,3,3,5> x;
};
它编译得很好。如果我尝试这样做:
class myclass{
myTensor_t<int,3,3,5> x=Zero_Tensor<int,3,3,5>();
};
我在编译时收到以下错误:
src/mytensor.hpp(107): error: no instance of overloaded function "Zero_Tensor" matches the argument list
res[i] = Zero_Tensor<U, M...>();
^
src/mytensor.hpp(112): note: this candidate was rejected because function is not visible
myTensor_t<U, N> Zero_Tensor(){
^
src/mytensor.hpp(104): note: this candidate was rejected because at least one template argument could not be deduced
myTensor_t<U, N, M...> Zero_Tensor(){
^
detected during:
instantiation of "myTensor_t<U, N, M...> Zero_Tensor<U,N,M...>() [with U=int, N=5UL, M=<>]" at line 107
instantiation of "myTensor_t<U, N, M...> Zero_Tensor<U,N,M...>() [with U=int, N=3UL, M=<5UL>]" at line 107
instantiation of "myTensor_t<U, N, M...> Zero_Tensor<U,N,M...>() [with U=int, N=3UL, M=<3UL, 5UL>]" at line 36 of "src/myclass.hpp"
我真的不明白this candidate was rejected because function is not visible
在告诉我什么。我想我不明白为什么它不可见?任何帮助,不胜感激。
建议:重写Zero_Tensor()
函数
template <typename U>
U Zero_Tensor ()
{ return U(0); }
template <typename U, std::size_t N, std::size_t... M>
myTensor_t<U, N, M...> Zero_Tensor ()
{
myTensor_t<U, N, M...> res;
for ( auto i = 0u ; i < N ; ++i )
res[i] = Zero_Tensor<U, M...>();
return res;
}
现在你的问题是地面版本(递归的结束,<U, N>
版本(是在递归版本(<U, N, M...>
(之后定义的,所以当递归版本调用
Zero_Tensor<U, M...>();
并且M...
包为空,编译器不知道仅接受U
类型作为模板参数的Zero_Tensor()
函数。
您可以反转定义的顺序(或在递归情况之前声明基本大小写(,但您还有另一个问题:当您调用时
Zero_Tensor<U, M...>();
并且M...
包只包含一个数字,您有一个模棱两可的调用,因为两个版本都匹配。
解决方案:使用更简单的接地案例
template <typename U>
U Zero_Tensor ()
{ return U(0); }
并在递归情况之前定义它。
这样
Zero_Tensor<U, M...>();
永远不会模棱两可,因为当M...
包为空时,只有地面大小写匹配,否则只有递归大小写匹配。
题外话建议:当你有一个从零到无符号数字的循环时(如你的例子(
// ............V N is std::size_t, an unsigned type
for(int i=0; i<N; i++)
对索引变量(i
(使用无符号变量以避免恼人的警告,如"警告:不同有符号的整数表达式的比较:'int'和'long unsigned int'">
问题是,当您在M...
为空的情况下实例化Zero_Tensor
时,Zero_Tensor
的另一个重载(只有 2 个模板参数(是不可见的。如果在参数包版本之前移动该重载,则在传入 2 个模板参数时会遇到重载不明确的问题。
您可以通过只有一个Zero_Tensor
函数来解决此问题,该函数根据M...
的大小决定要做什么,如下所示:
template<typename U, std::size_t N, std::size_t... M>
myTensor_t<U, N, M...> Zero_Tensor(){
myTensor_t<U, N, M...> res;
for(int i=0; i<N; i++)
if constexpr(sizeof...(M) > 0)
res[i] = Zero_Tensor<U, M...>();
else
res[i] = U(0);
return res;
};
这是一个演示。请注意,这需要 c++17。
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- C++ 实例化新对象时不接受继承方法默认参数值
- 收集有关在程序中实例化哪些模板变体的信息
- vc++函数模板实例化错误C2664当使用不同的枚举实参时
- 禁止使用迭代器形参实例化函数模板
- 虚拟继承,显式实例化——返回派生类引用/指针(协变类型)