重新解释转换模板非类型参数:clang c ++ 14 vs c ++ 1z

时间:2016-05-18 16:15:16

标签: c++ clang c++14 c++17

请考虑以下代码:

template <int* > struct foo { };

int main() {
    foo<(int*)42> f;
    (void)f;
}

在使用-std=c++11-std=c++14编译clang 3.8.0时,程序会编译。使用-std=c++1z进行编译时,错误为:

main.cpp:4:9: error: non-type template argument is not a constant expression
    foo<(int*)42> f;
        ^~~~~~~~
无论C ++模式如何,gcc 5.3.0都不编译代码,我认为这是正确的。 C ++ 14和C ++ 1z之间的clang有什么区别?为什么它接受代码? C ++ 1z中有什么变化与此相关吗?

1 个答案:

答案 0 :(得分:2)

使用godbolt表明在-std=c++1z模式下,Clang 3.5.1接受代码但3.6.0拒绝它。 changelog表示此版本是在添加对C ++ 1z功能的支持时,即&#34;对所有非类型模板参数的常量评估&#34;。我的猜测是C ++ 11和C ++ 14模式使用C ++ 11规则,而C ++ 1z模式使用C ++ 1z /最新草案规则。当然,程序在C ++ 11/14模式下被认为是有效的这一事实本身就是一个错误。

以下是一些类似(但不是直接相关)案例的错误报告:

Bug 18043 - allow arbitrary address constant expressions as non-type template arguments as an extension

Bug 10398 - Clang won't accept a null pointer constant as a non-type template argument

Bug 10396 - clang crashes during name mangling with as non-type template parameter

Bug 9700 - Null pointer not accepted as non-type template argument