代码之家  ›  专栏  ›  技术社区  ›  Kaelin Colclasure

为int8_t和uint8_t专门化这个模板函数的更好方法是什么?

  •  1
  • Kaelin Colclasure  · 技术社区  · 11 年前

    考虑模板 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专门化这个模板函数的更好方法是什么?

    1 回复  |  直到 11 年前
        1
  •  1
  •   Billy ONeal IS4    11 年前

    创建另一个函数模板,该模板设计为仅适用于uint8_t和/或int8_t,并将 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应保留用于无法通过更简单的方法实现的情况,因为它会产生较差的错误消息)