Я наткнулся на некоторый код, написанный на VS7.1, и теперь я пытаюсь заставить его работать на MacOSX.Я понимаю, что фрагмент кода ниже о SFINAE принципе .Из того, что я понимаю, код используется во время компиляции, чтобы знать, что это за тип, полагаясь на некоторую магию создания шаблона.Короче говоря, правильная перегрузка определяется путем просмотра аргумента шаблона.
Вот код, который у меня есть.Несколько упрощенно, чтобы показать только проблему.
template <typename T>
struct SomeClass
{
};
template <>
struct SomeClass<char>
{
typedef char Type;
};
template <typename T>
struct IsChar
{
typedef char Yes;
typedef int No;
template <typename U>
static Yes Select(U*, typename SomeClass<U>::Type* p = 0);
template <typename U>
static No Select(U*, ...);
static T* MakeT();
const static bool Value = sizeof(Select(MakeT())) == sizeof(Yes);
};
Я просто использую это так:
if (IsChar<int>::Value)
{
...
При компиляции приведенный выше код хорошо работает , и этовыбирает самый верхний класс из-за отсутствия typedef для Type при использовании int.
Если я вместо этого теперь использую char ...
if (IsChar<char>::Value)
{
...
... компилятор будет жаловатьсянеоднозначный Выберите функции , потому что он не знает, какой из них использовать.Из того, что я прочитал, разрешение перегрузки дает наименьшее предпочтение параметру многоточия (...).Таким образом, он должен знать, чтобы выбрать первый.
Код работал нормально по крайней мере на VS7.1, но не на gcc для MacOSX и не на gcc4.4 для Linux.
Anyпредложения как это исправить?Может быть, это обычно делается по-другому?
Спасибо!
ОБНОВЛЕНИЕ: я понял, что пример кода, который я дал, может быть немного слишком упрощен, потому что я считаю, что мы не проверяем jsut на типздесь, даже если я по ошибке заставляю это выглядеть так.Я должен буду собрать немного больше информации для вас сегодня вечером, потому что у меня нет кода здесь.Извините за это.
ОБНОВЛЕНИЕ2: Даже если моя презентация плохая, и это из-за того, что вы не знакомы с оригинальным кодом или не используете шаблоны таким образом.Тем временем я собираю немного больше информации, давайте предположим, что эти конструкции существуют по какой-то причине, и все имена, которые я дал, неверны, как насчет проблемы с компилятором?Почему он не может выбрать правильную перегруженную функцию здесь?Это тоже мне интересно.Как я уже сказал, я вернусь с более подробным объяснением общей цели.
Редактировать
После более внимательного изучения исходного кода он используетboost :: integra_constant, а также boost :: enable_if, как было предложено здесь.Проблема связана с тем, как выводятся аргументы шаблона, и это не сработало так, как было настроено.Однако, следуя тому, что Георг предложил в конце своего ответа, я мог исправить вещи, чтобы принять вещи.У меня сейчас следующее:
typedef char Yes;
typedef int No;
template <typename U> static Yes Select(typename SomeClass<U>::Type* p);
template <typename U> static No Select(...);
static const bool Value = sizeof(Select<T>(0)) == sizeof(Yes);
Это хорошо работает.Немного поэкспериментировав, я обнаружил, что наличие двух параметров функции в функциях выбора приводит к проблеме.Я не нашел причину.Я вернусь к этому, когда пойму лучше.
Спасибо за вашу помощь.По крайней мере, теперь я понимаю принципы и то, как все должно работать.Только некоторые детали, которые пока неизвестны.