C++力模板参数
我希望这段代码是可能的。
template<typename K, typename T, typename Comparer>
class AVLTree
{
...
void foo() {
...
int res = Comparer::compare(key1, key2);
...
}
...
};
具体来说,我想强制 Comparer 类具有 static int Compare(K key1, K key2)
函数。我正在考虑使用推导,但找不到任何可以使用模板的想法。
谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你不能。但是,如果使用该函数而比较器没有它,您的编译将失败,这或多或少是您想要发生的情况。是的,就像其他人指出的那样,您想将静态称为静态。
You can't. But if use the function and the Comparer doesn't have it, your compile will fail and this is more or less what you want to happen. And yes, like others pointed out you want to call static as static.
您是否尝试这样做:
在 C++ 中,静态函数可以通过两种方式调用:
Did you try doing:
In C++ Static functions can be called in two ways:
Michael 已经提到如果
Comparer
没有所需的成员函数。但是,如果您更担心简洁的错误消息,请使用类似 this 来检测类是否具有必需的成员函数并将其与诸如 Boost.StaticAssert:
Michael already mentioned that this will not compile if
Comparer
doesn't have the required member function.If however you're more worried about concise error messages, use something like this to detect if the class has a required member function and combine it with something like Boost.StaticAssert:
它必须是
Comparer::Compare
,对吧? (因为您正在调用类型上的静态函数)。您的 Comparer 类必须定义如下:
It would have to be
Comparer::Compare
, right? (Since you are calling a static function on a type).Your Comparer class would have to be defined as follows:
据我了解,您正在寻找更好的错误消息,以防模板参数不符合模板主体的要求。该语言没有内置的特殊机制,但人们使用库来近似它。请参阅 Boost 概念检查
I understand it you're looking for a better error message in case the template parameter doesn't fit the requirements of the template body. the language doesn't have an special mechanism for that built in, but people approximate it using libraries. see Boost Concept Check
对此进行编译时断言的松散方法是获取 Comparer::compare 的地址并将其分配给声明为 int(K, K) *func 的变量。
如果它是静态函数,则该分配将起作用,但如果它是成员函数,则该分配将不起作用。
我只是贡献这个,但我会采取使用 boost 习语的方法,因为这是手工制作的,可以这么说。
The loose approach of having a compile time assertion around this is to take the address of Comparer::compare and assign it to a variable declared as int(K, K) *func.
That assignment will work if it's a static function, but will not work if it's a member function.
I am just contributing this, but I would take the approach of using the boost idioms as this is hand-rolled, so to speak.
这是一种更惯用和通用的方法:
Comparer 不应该是定义静态
Compare
方法的类型。它应该是一个可以用函数调用语法调用的类型。这允许您使用函数对象的函数指针,并且允许您重用标准库中或几乎任何其他重要的 C++ 应用程序中已定义的比较器。它允许您在 C++0x 中添加 lambda 时使用它们。至于强制
Comparer
按预期行事? int res = cmp(key1, key2); 行已经确保了这一点。如果尝试传递无法以这种方式调用的类型,则会出现编译错误。您的原始代码中的情况也是如此。如果您传递的类型没有静态
Compare
方法,则会出现编译错误。所以你原来的代码已经解决了这个问题。Here's a more idiomatic and generic approach:
Comparer should not be a type that defines a static
Compare
method. It should be a type which can be called with function call syntax. That allows you to use function pointers of function objects, and it allows you to reuse the comparers already defined in the standard library, or in pretty much any other nontrivial C++ application. It allows you to use lambdas when they're added in C++0x.As for forcing
Comparer
to behave as expected? The lineint res = cmp(key1, key2);
already ensures that. If you try to pass a type that can't be called in this way, you get a compile error.The same was the case in your original code. If you passed a type that didn't have a static
Compare
method, you'd get a compile error. So your original code already solved the problem.正如已经指出的,您不能强制 Compare 有一个静态成员
compare
。如果您的比较器没有实现它,您只会收到编译器错误。如果你像这样实现
AVLTree
,那么将Comparer
声明为模板模板参数会更优雅:请参阅:http://codepad.org/OLhIPjed
As already pointed out, you can't force Compare to have a static member
compare
. If your comparer doesn't implement it, you just get an compiler error.If you implement
AVLTree
like this it would be more elegant to declareComparer
as a template template parameter:see: http://codepad.org/OLhIPjed