具有删除的“一般” case无法使用g ++< = 4.8.0和clang ++进行编译 [英] Specialized template function with deleted "general" case fails to compile with g++ <=4.8.0 and clang++

查看:213
本文介绍了具有删除的“一般” case无法使用g ++< = 4.8.0和clang ++进行编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用旧版本的g ++(4.8.0,MinGW)编译项目我发现此代码无法编译:

  template< typename T> 
void foo()= delete;

模板<>
void foo< int>(){}

int main(){
foo< int>()
return 0;
}

似乎g ++甚至没有尝试寻找显式专用化

  mitalia @ mitalia:〜/ scratch $ / opt / mingw32-dw2 / bin / i686 -w64-mingw32-g ++ -std = c ++ 11 buggy_deleted_template.cpp 
buggy_deleted_template.cpp:在函数'int main()':
buggy_deleted_template.cpp:8:14:error:use of deleted function'void foo()[with T = int]'
foo< int>();
^
buggy_deleted_template.cpp:5:6:错误:在此处声明
void foo< int>(){}
^
mitalia @ mitalia:〜/ scratch $ / opt / mingw32-dw2 / bin / i686-w64-mingw32-g ++ --version
i686-w64-mingw32-g ++(rubenvb-4.8.0)4.8.0
版权所有免费软件基金会,
这是免费软件;请参阅复制条件的来源。有NO
保修;甚至不适用于适销性或特定用途的适用性。

相反,g ++ 4.8.4和5.2(在Linux上)不抱怨。这是旧版本编译器中的错误还是标准中的灰色区域?






附录



clang 3.4.1似乎不太喜欢:

  mitalia @ mitalia:〜/ scratch $ clang ++ -std = c ++ 11 buggy_deleted_template.cpp 
buggy_deleted_template.cpp:5:6:error:redefinition'foo'
void foo< int>(){}
^
buggy_deleted_template.cpp:5:6:注意:以前的定义是这里
buggy_deleted_template.cpp:8:5:错误:函数调用'foo'
foo< int>();
^ ~~~~~~~
buggy_deleted_template.cpp:2:6:注意:候选模板忽略:替换失败[with T = int]
void foo()= delete;
^
生成2个错误。
mitalia @ mitalia:〜/ scratch $ clang ++ --version
Ubuntu clang版本3.4-1ubuntu3(标签/ RELEASE_34 / final)(基于LLVM 3.4)
目标:x86_64-pc-linux -gnu
主题模型:posix

(和 @Baum mit Augen 在注释报告中,它仍然不工作在3.7)

解决方案

我不知道如果以下将但我发现缺陷报告941:删除的功能模板的显式专门化(Emphasis Mine): p>根据14.7.3 [temp.expl.spec]段落1,只有未删除的
功能模板可以被明确地专门化。 没有
似乎是这个限制的迫切需求,然而,它
可能是有用的禁止使用隐式实例化的
特化,同时仍然允许明确使用



建议的解决方案(2010年2月):



更改14.7.3 [temp.expl.spec]第1段如下:



明确表示以下任一项:



未删除的函数模板



类模板



del>非删除类模板的成员函数



类模板的静态数据成员



类模板的成员类



类或类模板的成员类模板



类或类的非删除成员函数模板
模板



可以声明...


现在标准草案的当前状态 N4527 14.7.3显式专业化[temp.expl.spec]:




1



(1.1) - 函数模板

) - 类模板



(1.3) - 变量模板





(1.5) - 类模板的静态数据成员



模板



(1.7) - 类模板的成员枚举



(1.8)类或类模板



(1.9) - 类或类模板的成员函数模板




所以我想:

  template< typename T> 
void foo()= delete;

模板<>
void foo< int>(){}

int main(){
foo< int>()
return 0;
}

是C ++ 11标准兼容代码,应该接受。


Compiling a project with an older version of g++ (4.8.0, MinGW) I found that this code fails to compile:

template<typename T>
void foo() = delete;

template<>
void foo<int>(){}

int main() {
    foo<int>();
    return 0;
}

It seems that g++ doesn't even try to look for explicit specializations if it sees that the base case is deleted.

mitalia@mitalia:~/scratch$ /opt/mingw32-dw2/bin/i686-w64-mingw32-g++ -std=c++11 buggy_deleted_template.cpp 
buggy_deleted_template.cpp: In function 'int main()':
buggy_deleted_template.cpp:8:14: error: use of deleted function 'void foo() [with T = int]'
     foo<int>();
              ^
buggy_deleted_template.cpp:5:6: error: declared here
 void foo<int>(){}
      ^
mitalia@mitalia:~/scratch$ /opt/mingw32-dw2/bin/i686-w64-mingw32-g++ --version 
i686-w64-mingw32-g++ (rubenvb-4.8.0) 4.8.0
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Instead, g++ 4.8.4 and 5.2 (on Linux) do not complain. Is this a bug in the older version of the compiler or a gray area in the standard?


Addendum

clang 3.4.1 too seems not to like it:

mitalia@mitalia:~/scratch$ clang++ -std=c++11 buggy_deleted_template.cpp                                                             
buggy_deleted_template.cpp:5:6: error: redefinition of 'foo'                                                                         
void foo<int>(){}
     ^
buggy_deleted_template.cpp:5:6: note: previous definition is here
buggy_deleted_template.cpp:8:5: error: no matching function for call to 'foo'
    foo<int>();
    ^~~~~~~~
buggy_deleted_template.cpp:2:6: note: candidate template ignored: substitution failure [with T = int]
void foo() = delete;
     ^
2 errors generated.
mitalia@mitalia:~/scratch$ clang++ --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix

(and @Baum mit Augen in the comments reports that it still doesn't work in 3.7)

解决方案

I don't know if the following will be enlightening but I found defect report 941: Explicit specialization of deleted function template with status C++11 that states the following (Emphasis Mine):

According to 14.7.3 [temp.expl.spec] paragraph 1, only non-deleted function templates may be explicitly specialized. There doesn't appear to be a compelling need for this restriction, however, and it could be useful to forbid use of implicitly-instantiated specializations while still allowing use of explicitly-specialized versions.

Proposed resolution (February, 2010):

Change 14.7.3 [temp.expl.spec] paragraph 1 as follows:

An explicit specialization of any of the following:

non-deleted function template

class template

non-deleted member function of a class template

static data member of a class template

member class of a class template

member class template of a class or class template

non-deleted member function template of a class or class template

can be declared...

Now the current state of the draft standard N4527 is 14.7.3 Explicit specialization [temp.expl.spec]:

1 An explicit specialization of any of the following:

(1.1) — function template

(1.2) — class template

(1.3) — variable template

(1.4) — member function of a class template

(1.5) — static data member of a class template

(1.6) — member class of a class template

(1.7) — member enumeration of a class template

(1.8) — member class template of a class or class template

(1.9) — member function template of a class or class template

...

So I guess:

template<typename T>
void foo() = delete;

template<>
void foo<int>(){}

int main() {
    foo<int>();
    return 0;
}

Is C++11 standard compatible code and should be accepted.

这篇关于具有删除的“一般” case无法使用g ++&lt; = 4.8.0和clang ++进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆