免責事項:あなたがやっていることのために本当にテンプレートが必要かどうかを判断することはできません. これは、Adddition クラス テンプレートで使用するさまざまな型の数によって異なります。のみに使用する場合はint
、不要な複雑さが生じる可能性があります。後でいつでもリファクタリングできます (これがアジャイル アプローチです)。
そうは言っても、テンプレートを使用する場合、通常の規則はT
テンプレート パラメーターを記述し、クラス テンプレート内にtype
ネストされたを使用することです。orのtypedef
使用は好みの問題ですが、組み込み型も引数として渡すことができるという事実を強調します。ただし、template-template パラメーターを使用すると、次のように記述する必要があることに注意してください。typename
class
typename
template<template<typename> class U> SomeClass { /* your definition */ };
^^^^^ // <-- NOT typename here
これは、引数として渡すことができるのはクラス テンプレートのみであるという事実を強調しています。
コンパイルに失敗する可能性のあるコードについて言及できる他のいくつかの小技があります (戻り値の型がconvert()
欠落しており、クラス定義にセミコロンが欠落しています)。
template <typename T>
class Addition
{
static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
T num_a;
T num_b;
void convert(T const*, T const*); // by T const*, not T*
public:
Addition(T const&, T const&); // by T const&, not T
}; // <-- make sure to end class definitions with a semi-colon!
template <typename T>
Addition::Addition(T const& a, T const& b)
{
convert(&a, &b);
num_a = a;
num_b = b;
}
template <typename T>
void Addition::convert(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
^^^^ // <-- you forgot the return type
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
// converting
}
C++11 では、委譲コンストラクター(最新の Visual C++ ともちろん gcc/Clang でサポートされています) を使用して、
template <typename T>
Addition::Addition(T const& a, T const& b)
:
Addition(&a, &b) // delegate to the other constructor
{}
template <typename T>
Addition::Addition(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
// converting
}
最後に、テンプレート定義はとにかくヘッダーにある必要があるため、次のようにクラス定義内にすべてを記述することもできます。
template <typename T>
class Addition
{
static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
T num_a;
T num_b;
Addition(T const*, T const*) // by T const*, not T*
{
int temp_a = a, temp_b = b;
a = char[N], b = char[N];
// converting
}
public:
Addition(T const&, T const&) // by T const&, not T
:
Addition(&a, &b) // delegate to the other constructor
{}
}; // <-- make sure to end class definitions with a semi-colon!
これにより、すべてのメンバー関数の宣言と定義の両方を面倒に書く必要がなくなります。短くて甘いクラス (とにかく努力する必要があります) の場合、これはテンプレートを記述する好ましい方法ですが、非常に長い定義の場合は、宣言と定義を分離することをお勧めします。
最後に、@tacp で説明されているようにthis->a
、関数パラメーターからクラス データ メンバーを明確にするために使用する必要があります。そのため、多くの場合、末尾にアンダースコアまたはm_
プレフィックスを付けてデータ メンバーを記述します。