Рассмотрим шаблон 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?
Создайте другой шаблон функции, который предназначен для работы только с 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 должен быть зарезервирован для случаев, которые иначе не могут быть выполнены более простыми средствами, потому что это приводит к плохим сообщениям об ошибках)
Других решений пока нет …