Здравствуйте, Андрей Тарасевич, Вы писали:
АТ> Но вот функциональные типы по-прежнему проскальзывают сквозь слишком широкую дыру:
Думаю, проще будет определить функциональный тип, чем удачно прикрыть на "пациенте"...
А я пока про вторую часть исходной задачи, определить размер. Все бы просто, но есть типы int[] и т.п. Которые, признаются полноценными массивами.
Мое решение:
template<class U> class ArrayLenght {
template<class T>
static T & GetType(T*);// Обретение type[] размеров.static U * make();
enum {value = sizeof( GetType(make()) ) / sizeof( **make() ) };
};
template<class T>
class Capacity {
template<bool C = true >
struct IF {
enum { value = ArrayLenght<T>::value };
};
template<>
struct IF<false> {
enum { value = 0 };
};
public:
enum {value = IF< ArrayTester<T>::value >::value };
};
Ключевой прием согласуется со стандартом? Если нет, то очень интересны Ваши решения!!!
PS: Так навороченно из-за того, что sizeof(int[]) невычислим...
А тогда is_array<int &> и прочие ссылки компилиться не будут.
Может написать выбирающий шаблон, который будет контролировать типы допустимые для возврата в нашем контексте?
С void легко разобраться, а вот с определением ссылки уже не так просто (пользуясь пересечением стандарта и MS)...
Так же, очень интересно удаление ссылки и указателя без использования частичной специализации.
А вобщем, еще раз повторюсь, это классное решение задачи
Функциональные типы: Поскольку у нас есть IsReference и IsArray которые одновременно принимают за свои — функциональные типы, казалось бы тривиальное решение считать те типы функциональными которые IsReference && IsArray... И для большинства случаев это действительно работает Особенно мощно можно протащиться от того, что это решение может распознать произвольный функциональный тип!!!
Однако серьезный подход подразумевает корректность на любом входе...
А мы можем инстанцировать шаблон типом Type[], который распознается и как массив и как ссылка одновременно. (Других таких типов я не знаю, подскажите, если знаете) Что приводит серьезной к проблеме...
Взглянем как реализована детекция функциональных типов в boost... Легко видеть, что эта реализация имеет явный изъян-исключение, она не компилируется на ссылках на функциональные типы, тем не менее, она правильно работает на Types[] (есть и не явный изъян, то что определяются функции лишь до некоторого конечного числа аргументов)
А все из-за не глубокомысленно ляпнутой строки кода:
static T* t;
Итого: используя эти два подхода можно получить определение массива, ссылки и функции. Которое будет работать лучше (правильней), чем boost!!!
Далее, подчеркну, что мой вычислитель размера можно применять к типам которые серьезно подозреваются на массивность. Технику не делать этого на чем попало, считаю тривиальной и не привожу.
ЗЫЖ Рассуждения относятся к моим вариантам кода соответствующим стандарту (спасибо, Андрей ) и к варианту Андрея. Вариант определения ссылки Павла в его недавней статье, лично мне не нравится, из-за проблем с CV квалификаторами.
Здравствуйте, Gregory, Вы писали:
G>Всем спасибо, господа! G>Собрав воедино все, что вы написали по данной теме, удалось получить работующий код(т):
...