Существует ли или как бы вы написали класс метафункций, который проверяет, совместим ли класс с boost::range
? Я хочу использовать boost::enable
идиома, что-то вроде
template <typename T>
Constructor::Constructor(const T& t, __attribute__((unused)) typename boost::enable_if<is_range_compatible<T> >::type* aux=NULL)
для соответствующего is_range_compatible
metafunction. Я знаю о is_container из pretty_print, который фиксирует множество случаев, но не все, что работает с boost::range
,
редактировать Это использует C ++ 03, поэтому у меня нет доступа к функциям C ++ 11. Я использую старый, gcc 4.1 и boost 1.51.
Ты имеешь ввиду enable_if
?
Если вы можете убедить проверки концепции Boost работать с ней с пользой (вместо того, чтобы макрос + ошибка компиляции, которую он использует сейчас), проверки как ForwardConceptRange
являются уже предоставлено.
В противном случае, является ли проблемой использование существующих BOOST_CONCEPT_ASSERT
вместо макроса?
Если вы обновитесь до Boost 1.54, есть хорошая библиотека под названием TTI. Он позволяет вам по желанию составлять мета-функции интроспекции черт типа, чтобы вы могли легко выделить свои собственные мета-предикаты, которые можно использовать для включения или отключения шаблонов функций. Хотя это хорошее упражнение метапрограммирования, я не рекомендую делать это в рабочем коде. Мне было трудно уловить «ложные негативы», которые возникают из-за деталей реализации контейнеров STL. Например, ассоциативные контейнеры, поставляемые с MSVC11, наследуют свои begin
а также end
функции-члены из базового класса, которые дают ложный отрицательный результат с мета-предикатами, сгенерированными BOOST_TTI_HAS_MEMBER_FUNCTION
, Несмотря на свое прозвище, Юесселес дал вам хороший совет: используйте концепции, поставляемые с Boost.Range, чтобы отклонить или принять тип внутри тела шаблона функции, такой как конструктор в вашем примере … Конечно, это не решит проблему. проблема конвертируемости для вашего Constructor
…
РЕДАКТИРОВАТЬ: пример, взятый из сердить:
#include <boost/tti/has_member_function.hpp>
#include <vector>
#include <map>
namespace tti_test {
BOOST_TTI_HAS_MEMBER_FUNCTION(begin);
// .. begin test class for mstest
// this succeeds in both variants
TEST_METHOD(has_const_member_function_begin_is_true_for_vector)
{
Assert::IsTrue(has_member_function_begin<
std::vector<int>::const_iterator (std::vector<int>::*)() const
>::value);
Assert::IsTrue(has_member_function_begin<
const std::vector<int>, std::vector<int>::const_iterator
>::value);
}
// this fails in both variants...
TEST_METHOD(has_const_member_function_begin_is_true_for_map)
{
Assert::IsTrue(has_member_function_begin<
std::map<int, int>::const_iterator (std::map<int, int>::*)() const
>::value);
Assert::IsTrue(has_member_function_begin<
const std::map<int, int>, std::map<int, int>::const_iterator
>::value);
}
// end test class for mstest
}