Подтвердить что ты не робот

Существует ли эквивалент <? расширяет T>, <? супер T> в С++?

  • Есть ли эквивалент <? extends T>, <? super T> в С++?

  • Кроме того, работает ли <? extends T>, <? super T>, даже если T является интерфейсом в Java?

4b9b3361

Ответ 2

В нем нет довольно приятного синтаксического сахара, как в Java, но он хорошо управляется с boost/type_traits. Подробнее см. http://www.boost.org/doc/libs/1_40_0/libs/type_traits/doc/html/index.html.

#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>

class Base {};
class Derived_from_Base : public Base {};
class Not_derived_from_Base {};

template<typename BASE, typename DERIVED>
void workOnBase()
{
    BOOST_STATIC_ASSERT((boost::is_base_of<BASE, DERIVED>::value)); 
}

int main()
{
    workOnBase<Base, Derived_from_Base>();     // OK
    workOnBase<Base, Not_derived_from_Base>(); // FAIL
    return 0;
}

1 > d:...\main.cpp(11): ошибка C2027: использование undefined type 'boost:: STATIC_ASSERTION_FAILURE' 1 > с 1 > [ 1 > x = false 1 > ]

Ответ 3

Чтобы ответить на второй вопрос: да. Что касается дженериков, интерфейсы обрабатываются так же, как и реальные классы.

Я оставлю первый вопрос более опытным людям С++.

Ответ 4

Вы можете ограничить диапазон параметра шаблона в С++, используя различные механизмы признаков, из которых есть возможности реализации в boost.

Обычно вы этого не делаете - причина, по которой синтаксис существует в Java и С#, заключается в том, что они используют generics, а не шаблоны.

Генераторы Java генерируют общий код, который использует виртуальную отправку из базового типа, а не генерирует код для каждого типа, используемого в качестве аргумента шаблона. Поэтому обычно вы используете ограничение, чтобы позволить вам вызывать методы для объектов типа, используемых в качестве параметра шаблона.

Поскольку С++ генерирует код для каждого типа, используемого в качестве параметра шаблона, ему не нужно знать о базовом типе для них.

Например, класс шаблона для матрицы будет использовать операторы +, -, * для целевого типа. In может затем использоваться для любого типа, который поддерживает эти операторы. Если бы это было произвольно ограничено double и int s, вы не могли бы использовать шаблон с complex<double> или запустить тест с типом, который поддерживает арифметику интервалов, даже если эти типы предоставляют эти операторы, а матричная библиотека будет действительна с их использованием.

Возможность работать с произвольными типами, которые имеют одинаковую форму, является мощью шаблонов и делает их более полезными. Это до клиентского кода, чтобы решить, действительно ли это использовать этот шаблон с этим типом (пока он компилируется), и клиент всегда прав. Неспособность работать с произвольными типами, которые имеют одинаковую форму, а требование указывать ограничения на методы вызова, отличные от методов java.lang.Object, является недостатком дженериков.

Ответ 5

Это расширение, которое, к сожалению, было удалено из черновика стандарта С++ 0x, поскольку оно "не было готово". Тем не менее, это можно моделировать с помощью статических утверждений (которые являются частью С++ 0x и Boost, как упоминалось здесь).

Ответ 6

Это сработало для меня:

#include <iostream>

class MyBase {}; 
class A : public MyBase {};    
class B {};

template <class T>
typename std::enable_if<!std::is_base_of<MyBase, T>::value>::type
Foo(T &v) {
    std::cout << "Foo 1" << std::endl;
}

template <class T>
typename std::enable_if<std::is_base_of<MyBase, T>::value>::type
Foo(T &v) {
    std::cout << "Foo 2" << std::endl;
}

int main() {
  A a;
  B b;
  Foo(a);
  Foo(b);
  return 0;
}