1

double および std::complex で機能するテンプレート クラスを作成しました。想定どおり、すべてのメソッドは .hpp ファイルにあります。1つを除くすべて。ある場所で double の 2 乗または std::complex のノルムを計算する必要があるため、メソッドを特殊化する必要がありました。「二重の特殊化」(A)についてより明示的に:

double a(2.0);
double b(0.0);
b = a*a;

「複雑な特殊化」 (B) の場合:

std::complex<double> a(2.0,3.0);
double b(0.0);
b = std::norm(a);

私の質問は次のとおりです。

  • double と complex の両方で機能する関数を使用して、これらの特殊化を回避する方法はありますか? ( std::norm は複雑な場合にのみ機能するため...)

  • または唯一の解決策は、特殊化 (A) の double a を複合体にキャストし、特殊化 (B) のみを一般的なテンプレートとして使用することです (二重と複合体の両方で機能します)。

4

4 に答える 4

3

独自の関数を正方形/ノルム ラッパーとして導入することで、発散ケースを最小限に抑えることができます。

template <typename T>
double square_or_norm(T x);

template<>
inline double square_or_norm(double x) { return x * x; }

template <>
inline double square_or_norm(std::complex<double> x) { return norm(x); }

次に、それを必要とする関数内で使用します。

template <typename T>
T computation(T x) {
  return some_code_with(x, square_or_norm(x));
}
于 2013-04-03T09:09:44.337 に答える
1

You could define two function template overloads (when it comes to function templates, overloading is usually preferable to specialization) called compute_norm(), one accepting std::complex and one accepting unconstrained types. The unconstrained template would invoke operator *, while the constrained template would invoke std::norm().

#include <complex>

template<typename T>
double compute_norm(T t)
{ return t * t; }

template<typename T>
double compute_norm(std::complex<T> const& t)
{ return std::norm(t); }

Then, your generic code that can work both with a double and with a complex<double> would call compute_norm():

#include <iostream>

template<typename T>
void foo(T&& t)
{
    // ...
    double n = compute_norm(std::forward<T>(t));
    std::cout << n << std::endl;
    // ...
}

For instance, the following program:

int main()
{
    double a(2.0);
    foo(a);

    std::complex<double> c(2.0, 3.0);
    foo(c);
}

Will output:

4
13

Here is a live example.

于 2013-04-03T09:15:14.587 に答える
0

関数のオーバーロードを使用しないのはなぜですか?

double myNorm(double);
double myNorm(std::complex<double>);


double myNorm(double x) {
    return x * x;
}
double myNorm(std::complex<double> x) {
    return std::norm(x);
}

実装を .cpp または (インライン化されている場合) ヘッダー ファイルに配置できます。

于 2013-04-03T09:17:13.763 に答える