考虑下面的模板dump
功能:
namespace {
using namespace Eigen;
using namespace std;
using namespace vMAT;
template <typename T>
NSString *
dump(NSString * prefix, T * A, vMAT_Size sizeA)
{
NSMutableString * dump = [NSMutableString stringWithString:prefix];
[dump appendString:@" = \n"];
Eigen::Map<Matrix<T, Dynamic, Dynamic>> DATA(A, sizeA[0], sizeA[1]);
stringstream out;
out << DATA << endl;
[dump appendFormat:@"%s", out.str().c_str()];
return dump;
}
template <> // Specialized so elements print as numbers instead of chars
NSString *
dump(NSString * prefix, int8_t * A, vMAT_Size sizeA)
{
NSMutableString * dump = [NSMutableString stringWithString:prefix];
[dump appendString:@" = \n"];
Eigen::Map<Matrix<int8_t, Dynamic, Dynamic>> DATA(A, sizeA[0], sizeA[1]);
stringstream out;
out << DATA.cast<int32_t>() << endl;
[dump appendFormat:@"%s", out.str().c_str()];
return dump;
}
template <> // Specialized so elements print as numbers instead of chars
NSString *
dump(NSString * prefix, uint8_t * A, vMAT_Size sizeA)
{
NSMutableString * dump = [NSMutableString stringWithString:prefix];
[dump appendString:@" = \n"];
Eigen::Map<Matrix<uint8_t, Dynamic, Dynamic>> DATA(A, sizeA[0], sizeA[1]);
stringstream out;
out << DATA.cast<uint32_t>() << endl;
[dump appendFormat:@"%s", out.str().c_str()];
return dump;
}
}
正如您所看到的,我已复制/粘贴/编辑它以专门化转储int8_t
和uint8_t
矩阵的方式。但这正是模板应该消除的那种疯狂!
我试图在原始函数中添加一个额外的模板typename AsT
参数,但是继续与编译器发生冲突抱怨这一行:
out << DATA.cast<AsT>() << endl;
Xcode抱怨cast<AsT>()
是一个“依赖模板”,并希望在它前面插入template
关键字...这似乎是无意义的语法,然后生成另一个编译器错误。
为int8_t和uint8_t专门化这个模板函数有什么更好的方法?
答案 0 :(得分:1)
创建另一个功能模板,该模板仅用于uint8_t和/或int8_t,并使您的dump
专门化调用其他功能模板。
或者,只需创建从函数模板dump
调用的函数的重载。这是一个展示其工作原理的示例:http://ideone.com/Z88DU6
我相信对你的代码这样做会看起来像下面这样,但我并不完全肯定,因为我从未使用过Objective-C(或Objective-C ++)。
// Note: I believe this works but am not a template wizard and have not tried
namespace {
using namespace Eigen;
using namespace std;
using namespace vMAT;
template <typename T>
inline Eigen::Map<Matrix<T, Dynamic, Dynamic>> get_printable_eigen(Eigen::Map<Matrix<T, Dynamic, Dynamic>> const& in)
{
return in;
}
// No specialization; simple overloads!
inline Eigen::Map<Matrix<int32_t, Dynamic, Dynamic>> get_printable_eigen(Eigen::Map<Matrix<int8_t, Dynamic, Dynamic>> const& in)
{
return in.cast<int32_t>();
}
inline Eigen::Map<Matrix<uint32_t, Dynamic, Dynamic>> get_printable_eigen(Eigen::Map<Matrix<uint8_t, Dynamic, Dynamic>> const& in)
{
return in.cast<uint32_t>();
}
template <typename T>
NSString *
dump(NSString * prefix, T * A, vMAT_Size sizeA)
{
NSMutableString * dump = [NSMutableString stringWithString:prefix];
[dump appendString:@" = \n"];
Eigen::Map<Matrix<T, Dynamic, Dynamic>> DATA(A, sizeA[0], sizeA[1]);
stringstream out;
out << get_printable_eigen(DATA) << endl;
[dump appendFormat:@"%s", out.str().c_str()];
return dump;
}
}
(可能还有其他解决方案使用enable_if
和类型特征,但SFINAE应保留用于无法通过简单方法完成的情况,因为它会产生较差的错误消息)