本征库:模板中的断言失败
Eigen Library: Assertions failed in a template
我有一个模板化函数,它应该生成一个编译时已知的固定大小 Vector,具体取决于模板参数:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc()
{
switch(nSize){
case 2: return ExternalLibrary::generate_Vector_2d();
case 3: return ExternalLibrary::generate_Vector_3d();
}
}
但是,当我编译这段代码时,我得到了一个失败的断言,因为 Vector_2d 尺寸不适合 3d 尺寸:
Eigen::Vector3d testVector3d = myFunc<3>(); // failed, because 3d doesn't fit the theoreticelly possible 2d
基本上,失败的断言是可以理解的,但当然这在运行时永远不会成为问题。我怎样才能绕过这个失败的断言?或者有没有比switch条件更优雅的方式?
谢谢!
只声明模板函数,不定义它,然后定义两个特化:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc();
template <>
Eigen::Matrix<double, 2, 1> myFunc<2>()
{
return ExternalLibrary::generate_Vector_2d();
}
template <>
Eigen::Matrix<double, 3, 1> myFunc<3>()
{
return ExternalLibrary::generate_Vector_3d();
}
编译器,虽然它会消除死代码作为优化,无论如何都必须验证死代码的有效性,这意味着它必须确保 return ExternalLibrary::generate_Vector_3d()
的类型可以转换为 Eigen::Matrix<double, 2, 1>
,即使可以证明 return 语句无法执行。因为不允许这种转换,所以会出现编译时错误。
通过将两个 return 语句分离到单独的专业化中,您消除了这个问题,因为它从函数中删除了 return ExternalLibrary::generate_Vector_3d();
语句, 可以 return Eigen::Matrix<double, 3, 1>
.
以外的东西
请注意,将 myFunc()
与 2 或 3 以外的 nSize
一起使用会导致 link 时错误。我们可以通过提供无法实例化的主体将此错误移至编译时,但(表面上)依赖于 nSize
以便编译器不会在使用之前尝试实例化它:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc()
{
// With C++11, the following line provides a more useful diagnostic. If
// you don't have C++11 support, remove it and the bad return statement
// will do the job, albeit with a more cryptic error message.
static_assert((static_cast<void>(nSize), false), "Invalid template parameter nSize");
return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
}
这将提供指向错误使用 myFunc()
的诊断。例如,如果没有 C++11 支持,您会看到类似以下内容:
main.cpp:12:12: error: cannot cast from type 'int' to pointer type 'class INVALID_NSIZE_PARAMETER **********'
return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:29:5: note: in instantiation of function template specialization 'myFunc<4>' requested here
myFunc<4>();
^
我有一个模板化函数,它应该生成一个编译时已知的固定大小 Vector,具体取决于模板参数:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc()
{
switch(nSize){
case 2: return ExternalLibrary::generate_Vector_2d();
case 3: return ExternalLibrary::generate_Vector_3d();
}
}
但是,当我编译这段代码时,我得到了一个失败的断言,因为 Vector_2d 尺寸不适合 3d 尺寸:
Eigen::Vector3d testVector3d = myFunc<3>(); // failed, because 3d doesn't fit the theoreticelly possible 2d
基本上,失败的断言是可以理解的,但当然这在运行时永远不会成为问题。我怎样才能绕过这个失败的断言?或者有没有比switch条件更优雅的方式?
谢谢!
只声明模板函数,不定义它,然后定义两个特化:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc();
template <>
Eigen::Matrix<double, 2, 1> myFunc<2>()
{
return ExternalLibrary::generate_Vector_2d();
}
template <>
Eigen::Matrix<double, 3, 1> myFunc<3>()
{
return ExternalLibrary::generate_Vector_3d();
}
编译器,虽然它会消除死代码作为优化,无论如何都必须验证死代码的有效性,这意味着它必须确保 return ExternalLibrary::generate_Vector_3d()
的类型可以转换为 Eigen::Matrix<double, 2, 1>
,即使可以证明 return 语句无法执行。因为不允许这种转换,所以会出现编译时错误。
通过将两个 return 语句分离到单独的专业化中,您消除了这个问题,因为它从函数中删除了 return ExternalLibrary::generate_Vector_3d();
语句, 可以 return Eigen::Matrix<double, 3, 1>
.
请注意,将 myFunc()
与 2 或 3 以外的 nSize
一起使用会导致 link 时错误。我们可以通过提供无法实例化的主体将此错误移至编译时,但(表面上)依赖于 nSize
以便编译器不会在使用之前尝试实例化它:
template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc()
{
// With C++11, the following line provides a more useful diagnostic. If
// you don't have C++11 support, remove it and the bad return statement
// will do the job, albeit with a more cryptic error message.
static_assert((static_cast<void>(nSize), false), "Invalid template parameter nSize");
return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
}
这将提供指向错误使用 myFunc()
的诊断。例如,如果没有 C++11 支持,您会看到类似以下内容:
main.cpp:12:12: error: cannot cast from type 'int' to pointer type 'class INVALID_NSIZE_PARAMETER **********'
return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:29:5: note: in instantiation of function template specialization 'myFunc<4>' requested here
myFunc<4>();
^