2017-01-19 10 views
8
#include <codecvt> 
#include <string> 
#include <locale> 

std::string to_gbk(const std::wstring& u16_str) 
{ 
     using Facet = std::codecvt_byname<wchar_t, char, std::mbstate_t>; 
     std::wstring_convert 
       <std::codecvt<wchar_t, char, std::mbstate_t>> 
       wstr_2_gbk(new Facet("zh_CN.GBK")); 

     return wstr_2_gbk.to_bytes(u16_str); 
} 

int main() 
{ 
     to_gbk(L""); 
} 

打ち鳴らすとVC:これはgccのバグですか? [OK]を、しかし、GCC 6.2出力の両方である++

[[email protected] ~]# g++ main.cpp 
In file included from /usr/include/c++/6.2.1/bits/locale_conv.h:41:0, 
       from /usr/include/c++/6.2.1/locale:43, 
       from main.cpp:3: /usr/include/c++/6.2.1/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = std::codecvt<wchar_t, char, __mbstate_t>]’: 
/usr/include/c++/6.2.1/bits/unique_ptr.h:236:17: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = std::codecvt<wchar_t, char, __mbstate_t>; _Dp = std::default_delete<std::codecvt<wchar_t, char, __mbstate_t> >]’ 
/usr/include/c++/6.2.1/bits/locale_conv.h:218:7: required from here 
/usr/include/c++/6.2.1/bits/unique_ptr.h:76:2: error: ‘virtual std::codecvt<wchar_t, char, __mbstate_t>::~codecvt()’ is protected within this context 
delete __ptr; 
^~~~~~ 
In file included from /usr/include/c++/6.2.1/codecvt:41:0, 
       from main.cpp:1: 
/usr/include/c++/6.2.1/bits/codecvt.h:426:7: note: declared protected here 
     ~codecvt(); 
    ^

が、これはgccのバグのですか?

+7

はhttp://en.cppreference.com/w/cpp/locale/wstring_convert/~wstring_convertでノートを参照してください。 –

+3

頻繁にプログラマーは、CPUのバグを疑い、その後コンパイラーや最新の彼らは自分自身のミスを見つける:) – i486

+2

@lateeveloperこれは答えです! – YSC

答えて

9

これはgccのバグですか?

いいえ。std::codecvtのデストラクタは保護されています。参照[locale.codecvt](標準草案):

template <class internT, class externT, class stateT> 
class codecvt : public locale::facet, public codecvt_base { 
// ... 
protected: 
    ~codecvt(); 
}; 
どうやら他の実装は、公衆に可視性を促進するために選択した

、それが標準で必要とされていません。


また(未A欠陥として決定)LWG issue 721を参照してください。

これは、ファセットの元のデザインの残念な結果です。

欠陥報告書はまた、このようなオブジェクトを作成する方法の例があります。

template<class I, class E, class S> 
struct codecvt : std::codecvt<I, E, S> 
{ 
    ~codecvt() 
    { } 
} 

... 

std::wstring_convert<codecvt<wchar_t, char, std::mbstate_t> >; 
+1

私は 'void main()'とLWGの問題とすべての人のBoから見ると驚いています –

+0

保護されていれば、 'codecvt'から新しいクラスを派生させることでエラーを回避できますか? –

+0

@ MarkRansom:これは、引用された例のように、@ MarkRansomの導出が –

関連する問題