Question

Consider the template dump function below:

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;
    }

}

As you can see, I've copy/paste/edited it to specialize how int8_t and uint8_t matrices are dumped. But this is exactly the sort of madness that templates are supposed to eliminate!

I have tried to add an additional template typename AsT parameter to the original function, but keep running afoul of the compiler complaining about this line:

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

Xcode complains that the cast<AsT>() is a "dependent template" and wants to insert the template keyword in front of it… Which seems to be nonsensical syntax that then generates yet another compiler error.

What is a better way to specialize this template function for int8_t and uint8_t?

Was it helpful?

Solution

Create another function template which is designed to only work with uint8_t and/or int8_t, and have your specializations of dump call that other function template.

Alternately, just create overloads of functions called from the function template dump. Here's an example demonstrating how that works: http://ideone.com/Z88DU6

I believe doing that to your code would look something like the following, but I'm not entirely positive this works given that I have never used Objective-C (or 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;
    }
}

(There are probably other solutions using enable_if and type traits but SFINAE should be reserved for cases which cannot otherwise be accomplished through simpler means because it produces poor error messages)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top