变量模板实例化期间函数不可见
Function not visible durring instantiation of variadic templates
我正在尝试创建一个returns 零填充数组数组的函数...
以下 Elegantly define multi-dimensional array in modern 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>
版本)定义after递归版本(<U, N, M...>
), 所以当递归版本调用
Zero_Tensor<U, M...>();
并且 M...
包是空的,编译器不知道 Zero_Tensor()
函数只接受 U
类型作为模板参数。
您可以颠倒定义的顺序(或在递归情况之前声明基本情况)但是您有另一个问题:当您调用
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’”
问题是,当您实例化 Zero_Tensor
且 M...
为空时,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;
};
这是 demo。请注意,这需要 c++17.
我正在尝试创建一个returns 零填充数组数组的函数... 以下 Elegantly define multi-dimensional array in modern 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>
版本)定义after递归版本(<U, N, M...>
), 所以当递归版本调用
Zero_Tensor<U, M...>();
并且 M...
包是空的,编译器不知道 Zero_Tensor()
函数只接受 U
类型作为模板参数。
您可以颠倒定义的顺序(或在递归情况之前声明基本情况)但是您有另一个问题:当您调用
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’”
问题是,当您实例化 Zero_Tensor
且 M...
为空时,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;
};
这是 demo。请注意,这需要 c++17.