【问题标题】:Why can't I pass template parameters on to another template?为什么我不能将模板参数传递给另一个模板?
【发布时间】:2010-12-30 10:34:32
【问题描述】:

好的,我将举一个简单的例子来说明我的问题:

void Increment(Tuple<int, int>& tuple) {
    ++tuple.Get<0>();
}

int main() {

    Tuple<int, int> tuple;

    tuple.Get<0>() = 8;

    Increment(tuple);

    printf("%i\n", tuple.Get<0>()); // prints 9, as expected

    return 0;

}

这编译得很好,一切都很好。 Increment 函数只是增加元组中的第一个元素,然后我打印该元素。但是,如果我的 Increment 函数可以用于任何类型的元素,那不是很好吗?

template <typename T>
void Increment(Tuple<T, T>& tuple) {
    ++tuple.Get<0>(); // <-- compile ERROR
}

int main() {

    Tuple<int, int> tuple;

    tuple.Get<0>() = 8;

    Increment<int>(tuple);

    printf("%i\n", tuple.Get<0>());

    return 0;

}

我的第二个示例在编译时出现以下错误:

error: expected primary-expression before ')' token

我正想方设法弄清楚这会导致问题的原因。由于模板参数是“int”,因此生成的代码应该与我的硬编码示例相同。我怎样才能让它工作?

【问题讨论】:

  • GMan 的回答中显示的使用的丑陋和棘手可能是 std 和 boost 元组都有免费的get 函数的原因:++get&lt;0&gt;(tuple);

标签: c++ templates parameters compilation


【解决方案1】:

应该是:

++tuple.template Get<0>();

与您需要typename 指定从依赖类型限定的类型一样,您需要template 指定从依赖类型限定的模板函数。

【讨论】:

  • 工作出色!在使用了这么多年 C++ 之后,我简直不敢相信我从未听说过。猜猜我不经常使用模板。谢谢!
  • @nonoitall:出于某种原因,它鲜为人知。 (也因为很多人使用 NSVC,没有它也能正常工作,所以人们从一开始就不会遇到这个问题。)
  • @GMan :MSVC++ 显然是不可移植的,对吧? (在这种情况下)
  • @Nawaz:这与二进制文件本身有关,而不是它的作用。 (例如,MS Word 是不可移植的。)我认为您的意思是不兼容;我认为,这是模棱两可的。它确实也接受格式良好的代码,因此在这方面它是合规的,但它不会像应有的那样诊断格式不正确的代码,因此在这方面它是不合规的(它可以被视为编译器扩展,允许格式错误的代码)。不过,我倾向于不,因为当我们说“它是否兼容”时,我们通常指的是“它是否遵循所有标准”而不是“它是否接受所有格式正确的代码”。
  • @GMan :感谢您的精彩解释和正确使用术语。 :-)
【解决方案2】:

由于 GMan 已经为您提供了正确的 answer,您仍然可以做的一件事是:您可以简单地编写 Increment(tuple) 而不是 Increment&lt;int&gt;(tuple)(后者的语法看起来有点复杂)。编译器足够智能,可以从 tupletype 推断 function-template-type

看到这个:http://www.ideone.com/juNOg

【讨论】:

  • 欢迎评论。我怀疑这是他为了让它发挥作用而测试各种东西的结果。
猜你喜欢
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 2011-08-28
  • 2022-08-14
  • 2011-09-14
相关资源
最近更新 更多