4

ヘッダーstd::basic_string< char, char_traits<char>, allocator<char> >によってtypedef(g ++)される完全な特殊化を定義しようとしています。<string>

問題は、最初に含めると<string>、g ++はtypedefをのインスタンス化と見なし、basic_stringエラーを表示することです。私が最初に専門分野を行う場合、問題はありません。

含まれた後、自分の専門分野を定義できるはず<string>です。それを可能にするために私は何をしなければなりませんか?

私のコード:

#include <bits/localefwd.h>

//#include <string> // <- uncommenting this line causes compilation to fail

namespace std {
template<>
class basic_string< char, char_traits<char>, allocator<char> >
{
public:
    int blah() { return 42; }
    size_t size() { return 0; }
    const char *c_str() { return ""; }
    void reserve(int) {}
    void clear() {}
};
}

#include <string>
#include <iostream>

int main() {
    std::cout << std::string().blah() << std::endl;
}

上記のコードは正常に機能します。ただし、最初の#include <string>行のコメントを外すと、次のコンパイラエラーが発生します。

blah.cpp:7: error: specialization of ‘std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ after instantiation
blah.cpp:7: error: redefinition of ‘class std::basic_string<char, std::char_traits<char>, std::allocator<char> >’
/usr/include/c++/4.4/bits/stringfwd.h:52: error: previous definition of ‘class std::basic_string<char, std::char_traits<char>, std::allocator<char> >’
blah.cpp: In function ‘int main()’:
blah.cpp:22: error: ‘class std::string’ has no member named ‘blah’

の52行目/usr/include/c++/4.4/bits/stringfwd.h

  template<typename _CharT, typename _Traits = char_traits<_CharT>,
           typename _Alloc = allocator<_CharT> >
    class basic_string;

私の知る限り、これはテンプレートの単なる前方へのデカレーションであり、g++が主張するようなインスタンス化ではありません。

の56行目/usr/include/c++/4.4/bits/stringfwd.h

   typedef basic_string<char>    string;

私の知る限り、これは単なるtypedefであり、インスタンス化でもありません。

では、なぜこれらの行が私のコードと競合しているのですか?コードが常に前に含まれていることを確認する以外に、これを修正するにはどうすればよい<string>ですか?

4

2 に答える 2

9

特殊化が外部リンケージを持つユーザー定義名に依存している場合にのみ、標準ライブラリを特殊化することが許可されます。charはこの要件を満たしていないため、未定義の動作が発生します。

これは、17.4.3.1 [lib.reserver.names]/1で指定されています。

発生する特定のエラーは、実装が特殊化しようとしているテンプレートをすでにインスタンス化しているためです。テンプレートに特殊化を提供する場合は、提供するパラメーターを使用してテンプレートをインスタンス化する前に行う必要があります。専門分野。

14.7.3 [temp.expl.spec] / 6

于 2010-04-23T21:10:49.487 に答える
0

原則として、名前空間 std で特性クラス以外のものを定義または特殊化するべきではありません。

basic_string を特殊化する代わりに、独自の名前空間に独自の文字データ型を作成し、その型に std::char_traits を特殊化する必要があります (名前空間 std には他に何もありません)。独自の名前空間 (C++ 標準に属し、ユーザーが変更してはならない名前空間 std ではありません) の型。

于 2010-04-23T21:18:30.000 に答える