1

考虑下面的模板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<AsT>()是一个“依赖模板”并想template在它前面插入关键字……这似乎是一种无意义的语法,然后会产生另一个编译器错误。

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

4

1 回答 1

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 应该保留用于无法通过更简单的方式完成的情况,因为它会产生糟糕的错误消息)

于 2013-04-17T02:41:32.740 回答