2009-11-27 123 views
17
  1. 在C++中是否有等效的<? extends T>,<? super T>在C++中是否有等效的<? extends T>,<? super T>?

  2. 另外,是否<? extends T>,<? super T>工作,即使T是Java中的接口?

+0

你需要什么用的?可能会有更简单,更类似于C++的解决方案,而不是试图模拟此Java功能 – jalf 2009-11-27 11:26:50

回答

2

回答第一部分:Restrict Template Function

JesperE有第二部分正确的答案。

+0

遵循如下规则:如果作为参数传递的类具有定义的必要方法,那么这是一种傻瓜检查。 经批准的课程将具备所有必要的功能。但相反并不总是如此。如果你有类似<的东西?扩展T>然后它是傻瓜证明,因为我们明确指定类层次结构 – user855 2009-11-27 07:10:31

+0

@ajay:如果你想限制类型参数作为基类,因为你完全使用基类接口,那么你是否需要使它成为一个模板?你可以通过引用来操作基类吗?这会为您带来您所需要的类型安全。通过模板,您可以定义不需要来自同一层次结构的类型的操作。这是他们的力量。如果在你的情况下这是不可行的,也许你可以更新有关你想要做什么以及C++功能可以帮助你实现的更多细节。 – 2009-11-27 07:37:41

+0

?扩展意味着基类型的任何子类。 – TofuBeer 2009-11-27 07:40:36

5

回答你的第二个问题:是的。就泛型而言,接口被视为与真实类相同。

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

12

它不像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:使用未定义类型的 '升压:: STATIC_ASSERTION_FAILURE' 1>使用 1> [ 1> X =假 1>]

3

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

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

Java泛型生成共享代码,该代码使用来自基本类型的虚拟分派,而不是为每个用作模板参数的类型生成代码。所以通常你使用的限制是为了允许你调用用作模板参数的类型的对象的方法。

由于C++为用作模板参数的每种类型生成代码,因此不需要知道它们的基本类型。

例如,矩阵的模板类将在其目标类型上使用+, - ,*运算符。然后可以用于支持这些操作员的任何类型。如果它被任意限制为double s和int s,那么您不能使用带有complex<double>的模板,或者使用支持区间算术的类型运行测试,即使这些类型提供了这些运算符,并且矩阵库也是有效的使用它们。

在具有相同形状的任意类型上工作的能力是模板的功能,并使它们更有用。客户端代码决定是否有效地使用该类型的模板(只要编译),并且客户永远是正确的。无法在具有相同形状的任意类型上工作,并且需要指定限制来调用除java.lang.Object以外的方法,这是泛型的一个弱点。

2

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

1

这为我工作:

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

问题早于'is_base_of'(和'enable_if'),今天这应该是默认的解决方案 – Ap31 2017-05-25 18:07:47

相关问题