Ste*_*and 33 c++ templates g++ static-assert c++11
我使用g ++ 4.6.3(目前是ubuntu 12.04的默认包),标志为c ++ 0x,我偶然发现:
template <typename T>
inline T getValue(AnObject&)
{
static_assert(false , "this function has to be implemented for desired type");
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
static_assertion failed "this function has to be implemented for the desired type"
Run Code Online (Sandbox Code Playgroud)
即使我还没有在任何地方调用此功能.
这是一个g ++错误吗?只有在代码中的某处调用此函数时,才应该实现此函数.
Jon*_*ely 50
标准在[temp.res]/8中说
不能为可以生成有效特化的模板定义发出诊断.如果无法为模板定义生成有效的专业化,并且未实例化该模板,则模板定义格式错误,无需诊断.... [注意:如果实例化模板,将根据本标准中的其他规则诊断错误.确切地说,这些错误被诊断出来是一个实施质量问题. - 结束说明]
没有可能的方法来实例化将要编译的函数模板,因此模板定义格式错误,因此即使未实例化,编译器也允许(但不是必需)拒绝它.
你可以让它像这样工作:
template<typename T>
struct foobar : std::false_type
{ };
template <typename T>
inline T getValue(AnObject&)
{
static_assert( foobar<T>::value , "this function has to be implemented for desired type");
}
Run Code Online (Sandbox Code Playgroud)
现在,编译器不能立即拒绝该函数模板,因为直到它被实例化,它不知道是否会有一个专门的foobar有value == true.实例化时,foobar<T>将实例化相关的特化,并且静态断言仍将失败,如期望的那样.
And*_*owl 26
那是因为条件不依赖于模板参数.因此,编译器甚至可以在实例化该模板之前对其进行评估,并在评估产生时生成相关的编译错误消息false.
换句话说,这不是一个错误.虽然只有在实例化模板后才能检查很多东西,但是编译器甚至可以执行其他有效性检查.这就是为什么C++具有两阶段名称查找的原因.编译器只是试图帮助您找到100%可能发生的错误.
这确实是一个注释,但需要一个代码示例。
神圣标准的措辞static_assert不限制其对实例化代码的影响。
然而,代码
template <typename T>
inline T getValue(int&)
{
typedef char blah[-1]; // Common C++03 static assert, no special semantics.
}
int main()
{}
Run Code Online (Sandbox Code Playgroud)
也无法使用 MinGW g++ 4.7.2 进行编译,这突出了这个问题。
我认为答案是 g++ 是正确的,而不会为此产生编译错误的 Visual C++ 11.0 是错误的,但我很难根据神圣标准的经文提供相关分析。
编译器差异的一个实际后果是,目前您不能依赖该行为。
| 归档时间: |
|
| 查看次数: |
11635 次 |
| 最近记录: |