手动实例化模板时出错

问题描述:

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

mainy.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 ++错误

[[email protected]:~/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和3.7铿锵的错误但是它似乎与Visual工作Studio 2015.

当我们试图实例化时遇到了这个问题却都包含<cstdio>之前<algorithm><cstdio>中有

namespace std { 
    using ::remove; 
} 

上什么怎么回事任何想法?

+0

是否需要使用上面列出的编译器版本?如果没有,您可以在https://godbolt.org上评估上面列出的代码,并使用不同的编译器查看生成的代码。 – AhiyaHiya

+0

您发布的代码与'cstdio'和'algorithm'中的'std :: remove'不完全相似。如果将'int foo(int)'添加到'bar'开始,[ideone.com](http://ideone.com/40xVXX)似乎没有问题。 –

+3

问题依然存在:上述代码是否合法?如果是这样,那么我们在gcc中发现了一个bug。如果不是,那么这个标准有一个问题。 – jlehrer

看起来像这与an ancient bug in gcc有关,在这里你不能通过使用ns::func明确地实例化一个模板,唯一的方法就是使用namespace ns { ... func; }来完成。这只是最近才修复的,并且与newer gcc your code will compile

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

+0

你能告诉我专业化正在宣布哪里吗?显式实例是否被认为是专门化的? – jlehrer

+0

@jlehrer是的,你是对的。 gcc中的这个错误虽然涉及到很多与ns :: func相关的问题 – Pavel