默认模板参数:为什么编译器会抱怨没有指定模板参数?

10

我有这段代码:

struct A{};

template<class T = A>
struct B {
    void foo() {}
};

B b; //Error: missing template arguments before 'b'
     //Error: expected ';' before 'b'
     //More errors
b.foo()

如果我将foo()作为一个模板函数,并使用相同的模板“签名”,编译器不会抱怨没有指定模板参数:

struct A {};

struct B {
    template<class T = A>
    void foo() {}
};

B b; //OK
b.foo()

为什么我需要为模板类指定带有默认参数的参数,但不需要为模板函数指定?我是否错过了某些微妙的地方?

原因是因为肯定存在模板参数推导失败。但我想知道为什么。


可能是 函数模板的默认模板参数 的重复问题。 - Peter Mortensen
3个回答

7
正确的语法是这样的(演示):
B<> b; 

对于类模板B,默认参数A被假定。<>部分告诉编译器B是一个类模板,并请求它将默认参数作为模板参数传递。


我明白了。但为什么模板函数可以在没有这个东西的情况下工作: b.foo<>() - badmaash
我的错。应该提到支持函数默认模板参数的g++ 4.7.0。所以上面的代码肯定可以工作。尝试使用g++ 4.7.0运行。 - badmaash
2
@Nawaz: 是的,它可以;你需要C++11来使用默认参数,但函数调用是正确的。函数模板可以在没有函数参数列表的情况下被调用;这允许重载解析同时考虑模板特化和非模板重载。 - Mike Seymour
为什么我不需要这样做:b.foo<>()?是因为这两种情况下的推断过程不同吗? - badmaash
@badmaash:正如Mike在他的评论中所说:“函数模板可以在没有函数参数列表的情况下被调用;这使得重载分辨率可以考虑模板特化和非模板重载。”这对我来说很有道理。 - Nawaz
显示剩余3条评论

1

正如Nawaz已经提到的那样,正确的语法是:

B<> b;

原因是B是模板,而B<>是使用默认参数A实例化模板。但当你需要一个实例化时,你需要<>来加以区分。

0

因为你必须声明 B 是一个模板:

B<> b;

即使您不想指定任何参数。


实际上,你需要使用 <> 来告诉编译器你不想要一个模板,而是使用默认参数来实例化一个模板。虽然语法是正确的。 - David Rodríguez - dribeas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接