将这个模板函数专门用于 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_tuint8_t 矩阵的转储方式。但这正是模板应该消除的那种疯狂!

我试图在原始函数中添加一个额外的模板typename AsT 参数,但一直运行与抱怨此行的编译器发生冲突:

out << DATA.cast<AsT>() << endl;

Xcode 抱怨 cast&lt;AsT&gt;() 是一个“依赖模板”,并希望在其前面插入 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 的更好方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Redis---set

专门化模板成员函数 [SFINAE]

由模板参数具体化的类型的模板特化

为模板函数专门化一个模板类

uint8与uint8_t区别

C ++中是否存在实际的8位整数数据类型