将这个模板函数专门用于 int8_t 和 uint8_t 的更好方法是啥?
Posted
技术标签:
【中文标题】将这个模板函数专门用于 int8_t 和 uint8_t 的更好方法是啥?【英文标题】:What is a better way to specialize this template function for int8_t and uint8_t?将这个模板函数专门用于 int8_t 和 uint8_t 的更好方法是什么? 【发布时间】:2013-04-17 02:38:22 【问题描述】:考虑下面的模板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 专门化此模板函数的更好方法是什么?
【问题讨论】:
对于您的第二个说明,它认为“cast”是类模板,而不是函数模板。你是怎么得到“AsT”的? (虽然这似乎是一个单独的问题) @BillyONeal:我正在尝试添加AsT
作为第二个模板参数。
【参考方案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 应保留用于无法通过更简单的方式完成的情况,因为它会产生糟糕的错误消息)
【讨论】:
很好……在上面的轻微变化下可以正常工作。谢谢!以上是关于将这个模板函数专门用于 int8_t 和 uint8_t 的更好方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章