【问题标题】:Error when manually instantiating a template手动实例化模板时出错
【发布时间】:2017-08-30 06:21:42
【问题描述】:

最近在我的公司,我们遇到了一个错误,我无法理解为什么它实际上是一个错误。对我们来说,这似乎应该编译得很好,并允许我们显式实例化一个 bar::foo 类型的模板。

ma​​iny.cxx

int foo(int);
namespace bar {
  template <typename T> T foo(T a, T){return a;}
}

namespace bar {
  using ::foo;
}

template int bar::foo(int, int);

int main(){
  return 0;
}

g++ 错误

[csteifel@host:~/test]1047 $ g++ mainy.cxx
mainy.cxx:10: error: 'int bar::foo(int, int)' should have been declared inside 'bar'
mainy.cxx:10: error: 'int bar::foo(int, int)' is not declared in '::'

我们已确认这是 gcc 4.8、4.4 和 clang 3.7 中的错误,但它似乎适用于 Visual Studio 2015。

当我们尝试实例化 std::remove 但在 &lt;cstdio&gt;&lt;cstdio&gt; 之前包含 &lt;algorithm&gt; 时遇到了这个问题

namespace std {
   using ::remove;
}

对这里发生的事情有什么想法吗?

【问题讨论】:

  • 是否需要使用上面列出的编译器版本?如果没有,您可以在godbolt.org 评估上面列出的代码,并使用不同的编译器查看生成的代码。
  • 您发布的代码与来自cstdioalgorithmstd::remove 并不完全相似。如果你把int foo(int)加到bar开头,ideone.com好像没有问题。
  • 问题依然存在:上面的代码合法吗?如果是这样,那么我们在 gcc 中发现了一个错误。如果不是,则标准存在问题。
  • 我试过g++ 6.3和clang++ 3.8,都编译没有错误,所以我猜你使用的旧编译器有错误。

标签: c++ visual-studio gcc clang


【解决方案1】:

看起来这与an ancient bug in gcc 有关,您不能使用ns::func 显式实例化模板,唯一的方法是使用namespace ns { ... func; } 来实现。这只是最近才通过newer gcc your code will compile 修复的。

顺便说一句,与您所说的相反,您的代码compiles with clang 3.7

【讨论】:

  • 你能告诉我一个专业化在哪里被前向声明吗?显式实例化是否被视为特化?
  • @jlehrer 是的,你是对的。 gcc 中的那个错误虽然有很多与ns::func 措辞相关的问题
猜你喜欢
  • 2012-10-29
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-17
  • 2015-05-08
  • 1970-01-01
相关资源
最近更新 更多