Rya*_*ing 16 c++ gcc clang constexpr c++11
我有一个模板化的类A和一个f返回A对象的模板化函数.我想f<T>成为朋友,现在A<T>仍然是constexpr
template <typename T>
class A;
template <typename T>
constexpr A<T> f();
//f<T> is a friend of A<T>
template <typename T>
class A {
friend /* constexpr? */ A f<T>();
constexpr A() {}
};
template <typename T>
constexpr A<T> f() { return {}; }
int main() {
constexpr auto a = f<void>();
}
Run Code Online (Sandbox Code Playgroud)
我不能让clang和gcc同意这里的内容.如果我没有constexpr输入好友声明,gcc工作正常但clang不会编译它,错误的:
main.cpp:18:18: error: constexpr variable 'a' must be initialized by a constant expression
constexpr auto a = f<void>();
^ ~~~~~~~~~
main.cpp:18:23: note: non-constexpr function 'f<void>' cannot be used in a constant expression
constexpr auto a = f<void>();
^
main.cpp:9:12: note: declared here
friend A f<T>();
Run Code Online (Sandbox Code Playgroud)
如果我constexpr在朋友声明中标记它,clang编译好,但gcc给我错误:
main.cpp:9:27: error: 'constexpr' is not allowed in declaration of friend template specialization 'A<T> f<T>()'
friend constexpr A f<T>();
Run Code Online (Sandbox Code Playgroud)
我怎样才能让每个人都开心?
int main() { constexpr auto a = f<void>(); }
Run Code Online (Sandbox Code Playgroud)
这专门将功能模板f作为功能f<void>(); 在专门化过程中f,编译器也会尝试实例化A<void>,而后者又会声明特化friend f<void>().
这两个声明必须匹配constexpr:
[dcl.constexpr]/1
[...]如果函数或函数模板的任何声明都有一个
constexpr说明符,那么它的所有声明都应该包含说明constexpr符.[ 注意:显式特化可以与模板声明相对于说明constexpr符不同.- 结束说明 ]
当您constexpr在friend声明中省略而不是删除看似非constexpr函数的内容时,Clang可能应该早先出错,但至少它接受正确的语法.
GCC不应该允许的版本失踪constexpr,并给出了一个错误,当你提供constexpr因错误.这已经在主干中得到修复,我现在可以确认它是有效的,虽然它在constexpr丢失时仍然没有提供错误.
| 归档时间: |
|
| 查看次数: |
398 次 |
| 最近记录: |