2015-09-25 49 views
5

考虑代码:错误时明确地将模板非类型参数

class Base{}; 
class Derived: public Base{}; 

template<Base& b> // references (and pointers) can be used as non-types 
void f(){} 

int main() 
{ 
    Derived d; 
    // f(d); // Error, template type must match exactly 
    f<(Base&)d>(); // Error here, why?! 
} 

我明白为什么评论调用失败:模板类型必须完全匹配。但是我尝试在第二个电话打石膏,并得到这个错误(gcc5.2):如果我做Derived d;全球

error: 'd' is not a valid template argument for type 'Base&' because it is not an object with external linkage

同样的错误。铿锵有点更有帮助,说

... note: candidate template ignored: invalid explicitly-specified argument for template parameter 'b'

我的问题是:是否代码上面的法律或不?如果不是,有什么理由为什么?

回答

4

此答案假定C++ 11或更高

两个问题这里:

1)任何派生到基转换为非类型模板参数[temp.arg。无类型]/P1

For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):

— a subobject (1.8),

2)该对象的地址应该是在编译时间。总结[temp.arg.nontype]/p1[expr.const]/p5因此它应该有static storage duration

把这两点结合起来,你就会有以下编译

class Base{}; 
class Derived: public Base{}; 

template<Base& b> // references (and pointers) can be used as non-types 
void f(){} 

Base obj; // Static storage duration 

int main() 
{ 
    f<obj>(); 
} 

Live Example

+0

另请参阅http://stackoverflow.com/questions/5687540/non-type-template-parameters – DrWatson

2

从[temp.arg.nontype]:

A template-argument for a non-type template-parametershall be a converted constant expression (5.20) of the type of the template-parameter.

有这里有两个问题。首先,d没有链接,因此您不能在常量表达式中引用它。这是一个简单的修复,但:

Derived d; 
int main() { 
    f<d>(); // still an error 
} 

现在,我们有另一个问题。我们进入下一句:

For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):
(1.1) — a subobject (1.8),

我们正在试图采取引用的Derived子对象(基类子对象)。无论连接如何,这都被明确禁止。

相关问题