简单的回答:使typedef公开。
这会泄漏实现的一个小细节(实际的内部类型),但是因为它是typedefed,你可以在任何时候重新定义它,它应该没问题。
简单一点:交友助手功能,提供访问您的内部类型。
第二种方法的问题在于,您不仅授予对typedef的访问权限,还授予对您班级的所有私有部分的访问权限,这可能不是最好的主意。无论如何,因为这是一个内部帮助函数,所以它是在你自己的控制之下的,它应该没问题。 (现在我想起来了,你可能想声明函数在一个命名的命名空间中,以使friend
声明成功)
更简单:在实现文件中创建一个单独的typedef,并确保它们是同步的。
您可以确保类型与一小段元编程相同,same_type<T,U>
模板将提供一个true
值(如果两个类型相同,否则为false)。如果typedef只在一个地方更改,则静态声明将触发错误
返回简单:提供typedef或直接使用类型,而不使用静态声明。
你正在调用一个函数(这不应该是你的代码中的模板),并传递一个引用。如果typedef在类中发生更改,则调用将失败,编译器会告诉您。
我会去的最后一个选项,虽然它可能看起来有点粗糙,少细腻比别人,但事实是,这是唯一没有被其他人一个实现细节,你完全控制之下的代码和好,简单就更好。
编辑,之后的评论。
我开始写这个作为评论,但它变得太长了,所以我将它添加到答案。
这个解决方案本身并没有什么错,除了不必要的做一个通用函数,以后一些错误信息可能不会像使用非通用签名那样简单。请注意,template
将而不是公开typedef
(问题标题建议),而是它会使编译器推断在调用的地方的类型。
如果更改typedef
,而不是得到一个错误,指出该参数helperFn
不能对现有的功能相匹配,则类型推断,功能匹配,但你会在helperFn
得到一个错误更深,如果你使用不再存在的类型的属性。或者更糟糕的是,如果这种类型的语义发生了变化,那么您甚至可能不会收到错误。
认为typedef的是std::list<X>
的,而且在你迭代它与这个简单的正确的for循环的功能:
for (typename T::iterator it=x.begin(), end=x.end(); it != end;) {
if (condition(*it))
it = x.erase(it);
else
++it;
}
你能赶上改变的typedef std::vector<X>
就会有效果?即使代码现在不正确,编译器也不能。是否这样写for for循环是一个好主意,或者为什么它不仅仅使用擦除 - 删除成语是不同的问题(事实上,前一个循环是可以说是更好的比擦除删除一个列表),具体情况是语义已经改变,并且因为类型在语法上与前一个兼容,所以兼容编译器不会注意到代码是错误的,它不会指向你的那个函数,并且机会是你不会审查/重写它。
为什么不把辅助函数的Foo'的私有成员'?你认为采取这种方法会失去什么? – ildjarn 2011-03-30 20:28:48
准确地说,模板将* not *暴露'typedef',而是让编译器在调用的地方解析类型。 – 2011-03-31 07:41:01
@dribeas,谢谢。这似乎有点奇怪,类型可以隐式地(由编译器)解决,但不是明确地(由我)解决。 – criddell 2011-04-01 13:02:15