12

どうか、私がやろうとしていることを見てください:

#include <iostream>
namespace first
{
 template <class T>
 class myclass
 { 
  T t;
 public:
  void who_are_you() const
  { std::cout << "first::myclass"; }
 };
}
namespace second
{
 using first::myclass;
 template <>
 class myclass <int>
 {
  int i, j;
 public:
  void who_are_you() const
  { std::cout << "second::myclass"; }
 };
}

これは許可されていません。スペシャライゼーションを異なる名前空間に含めることができない理由と、利用可能なソリューションを明確にしてください。また、C ++ 0xで修正されたものですか?

これにより、たとえば、?に何かを追加することで、未定義の動作に頼ることなく、、、などを専門std::max化することができます。std::swapstd::numeric_limits::std::


@AndreyTこれが私がそれを使う方法です:

// my_integer is a class
std::numeric_limits<my_integer>::max(); // specialized std::numeric_limits for my_integer

これはできますか?

4

3 に答える 3

7

C ++ 2003、§17.4.3.1/ 1:「プログラムは任意の標準ライブラリテンプレートのテンプレート特殊化を名前空間stdに追加できます。宣言がユーザーに依存しない限り、標準ライブラリテンプレートのそのような特殊化(完全または部分的)は未定義の動作になります-外部リンケージの定義された名前。スペシャライゼーションが元のテンプレートの標準ライブラリ要件を満たさない場合。」

そのため、ユーザー定義型に依存し、元のテンプレートの要件を満たしている限り、ライブラリテンプレートを特殊化し、名前空間に特殊化することができますstd

編集した質問にあるコードは、(おそらく)外部リンクを持つユーザー定義名の特殊化のようです。したがって、その部分に問題はないはずです。

それはあなたの専門分野が元のテンプレートの要件を満たすという要件だけを残します。あなたのタイプの場合、これのほとんどはおそらく些細なことに国境を接します。明らかではないかもしれない唯一の部分は、テンプレートだけでなく、テンプレート全体に特殊化を提供する必要があるように見えることですnumeric_limits::max()。つまり、次のようなことを行う必要があります(128ビットの符号なし整数型の例は球場にあるはずです):

namespace std { 
template <>
class numeric_limits<my_integer> {
public:

    static const bool is_specialized = true;
    static T min() throw() { return 0;
    static T max() throw() { return /* 2^128-1 */; } // ***
    static const int digits = 128;
    static const int digits10 = 38;
    static const bool is_signed = false;
    static const bool is_integer = true;
    static const bool is_exact = true;
    static const int radix = 2;
    static T epsilon() throw() { return 0; }
    static T round_error() throw() { return 0; }
    static const int min_exponent = 0;
    static const int min_exponent10 = 0;
    static const int max_exponent = 0;
    static const int max_exponent10 = 0;
    static const bool has_infinity = false;
    static const bool has_quiet_NaN = false;
    static const bool has_signaling_NaN = false;
    static const float_denorm_style has_denorm = denorm_absent;
    static const bool has_denorm_loss = false;
    static T infinity() throw() { return 0; }
    static T quiet_NaN() throw() { return 0; }
    static T signaling_NaN() throw() { return 0; }
    static T denorm_min() throw() { return 0; }
    static const bool is_iec559 = false;
    static const bool is_bounded = true;
    static const bool is_modulo = true;
    static const bool traps = false;
    static const bool tinyness_before = false;
    static const float_round_style round_style = round_toward_zero;
};
}

それらのかなりの数は実際にはFP型用であり、整数型にとって意味がある必要はありません。まだ実装する必要があると思います。

于 2010-06-18T19:04:19.883 に答える
5

それは物事を複雑にします:

namespace first
{
  template <class T> class TArray;
}

namespace second
{
  using first::TArray;

  template <class U> class TArray < Node<U> >;
  //                              ^
  // Only there do you realize it's a specialization and not another template
}

私はあなたの欲求不満を理解しています、私はしばしば同じことを望みました。それは間違いなく可能であり、論理的なグループ化の議論を購入することはありませんが、コンパイラの作成者の努力がさらに必要になることを認めなければなりません。C++を正しく解析することは、現状ではすでに十分に困難です。

私の意見が必要な場合、テンプレートはC ++では少し厄介ですが、経験の恩恵を受けて、20年の使用を見た後は簡単に言うことができます:)

于 2010-06-18T18:50:59.257 に答える
-4

なぜそのような質問が生じるのでしょうか?答え始めることすら難しいことを理解せずに。

スペシャライゼーションはメインテンプレートを変更します。メインテンプレートから「取り外し可能」ではありません。ある意味では、高レベルの概念として、それはまだ同じテンプレートです(低レベルでは独立したものとして定義されていますが)。したがって、明らかな理由から、メインテンプレートと同じ名前空間にあります。

申し訳ありませんが、そのような質問がどのように発生するかわからないため、これ以上の説明はできません。

ところで、「別の名前空間にある」とはどういう意味ですか?スペシャライゼーションを別の名前空間のメンバーにしますか?または、スペシャライゼーションをソースコードの別の名前空間で定義したいが、それでも元の名前空間のメンバーのままにしたいですか?

于 2010-06-18T18:43:12.383 に答える