是否相当于<! - ?扩展T - >,<! - ?超级T - >在C ++中?

时间:2009-11-27 05:43:22

标签: java c++ generics templates

  1. 在C ++中是否等同于<? extends T><? super T>

  2. 此外,即使<? extends T>是Java中的接口,<? super T>T也能正常工作吗?

6 个答案:

答案 0 :(得分:13)

它没有像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&gt; d:... \ main.cpp(11):错误C2027:使用未定义类型'boost :: STATIC_ASSERTION_FAILURE' 1 GT;同 1 GT; [ 1 GT; X =假 1 GT; ]

答案 1 :(得分:6)

回答你的第二个问题:是的。就泛型而言,接口的处理方式与实际类相同。

我会将第一个问题留给更多精通C ++的人。

答案 2 :(得分:3)

回答第一部分:Restrict Template Function

JesperE的第二部分答案正确。

答案 3 :(得分:3)

您可以使用各种特征机制限制C ++中模板参数的范围,其中有一些实现可用于增强。

通常你没有 - Java和C#中存在语法的原因是它们使用泛型而不是模板。

Java泛型生成共享代码,该代码使用基类型的虚拟分派,而不是为用作模板参数的每种类型生成代码。因此,通常使用限制是为了允许您在用作模板参数的类型的对象上调用方法。

由于C ++为每个用作模板参数的类型生成代码,因此无需了解它们的基本类型。

例如,矩阵的模板类将在其目标类型上使用+, - ,*运算符。然后,可以将其用于支持这些运算符的任何类型。如果它被任意限制为doubleint s,则您无法使用带有complex<double>的模板或运行支持区间运算的类型的测试,即使这些类型提供那些运算符,矩阵库使用它们是有效的。

处理具有相同形状的任意类型的能力是模板的强大功能,并使它们更有用。由客户端代码决定是否有效使用该类型的模板(只要它编译),并且客户始终是正确的。无法处理具有相同形状的任意类型,并且需要指定除java.lang.Object之外的调用方法的限制,这是泛型的弱点。

答案 4 :(得分:2)

这是一个extension,遗憾地从C ++ 0x标准草案中删除,因为它“尚未准备好”。但是,可以使用静态断言来模拟这个(这是人们在这里提到的C ++ 0x和Boost的一部分)。

答案 5 :(得分:2)

这对我有用:

#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;
}