C++問題-函數不同實作的統一介面

我想要用C++實作一個計算向量2-norm的函數,這個函數會根據向量的型態而有不同的實作:

#include <iostream>
#include <math.h>
#include <complex>

# 實數情況
void norm2(float* a, size_t n, float& res)
{
  res = 0;
  const float* const a_end = a + n;
  while (a < a_end){
    res += (*a)*(*a);
    ++a;
  }
  res = sqrt(res);
}

# 複數情況
void norm2(std::complex<float>* a, size_t n, float& res)
{
    res = 0;
    const float* p = (float*) a;
    const float* const p_end = p + 2*n;
    res=0;
    while (p < p_end)
    {
        res += (*p)*(*p);
        ++p;
    }
    res = sqrt(res);
}

如果向量的型態可以是double, interger, std::complex<double>std::complex<integer>的話,想請問有沒有什麼方法可以只定義一個廣義函數的介面,然後使用函數時會根據資料型態來決定呼叫哪個實作?


更新:
@yhmtsai 提供的解決辦法-使用function overload 加上 template

#include <iostream>
#include <math.h>
#include <complex>

# 實數情況
template <typename ValueType>
void norm2(ValueType* a, size_t n, ValueType& res)
{
  res = 0;
  const ValueType* const a_end = a + n;
  while (a < a_end){
    res += (*a)*(*a);
    ++a;
  }
  res = sqrt(res);
}

# 複數情況
template <typename ValueType>
void norm2(std::complex<ValueType>* a, size_t n, ValueType& res)
{
    res = 0;
    const ValueType* p = (ValueType*) a;
    const ValueType* const p_end = p + 2*n;
    res=0;
    while (p < p_end)
    {
        res += (*p)*(*p);
        ++p;
    }
    res = sqrt(res);
}

如果要不同實作的話,能用 template 配合 overload

template <typename ValueType>
void norm2(ValueType* a, size_t n, ValueType& res) {
  // 非複數
}

template <typename ValueType>
void norm2(std::complex<ValueType>* a, size_t n, ValueType& res) {
  // 複數
}

你 C++ 程式碼沒有被認為是 C++ :rofl:
可以在 ``` 後面加上 cpp

→ ``` cpp
這樣就可以讓用 cpp 的樣式

1個讚

感謝回答,因為我很少用C++不是很熟C++的術語,
overload 好像就是相同名字並有不同的實作的多個函數,感覺跟 Julia 的 multiple dispatch 很像,想請問在C++的overload中,什麼東西會被用來決定呼叫哪一個實作呢?

不是很嚴謹地說法,會挑比較"特殊"的或者說適用範圍比較小的來使用
你的例子比較不會遇到這個問題,因為第一項+最後一項就可以很好分辨出來了。
假如是以下的

// 1
template <typename ValueType>
void func(ValueType*) {}
// 2
template <typename ValueType>
void func(std::complex<ValueType>*) {}

func(std::complex<double>*);
可以是第一個當 ValueType = std::complex<double> 或者
第二個當 ValueType = double 的狀況
但由於第二個限用範圍較小,所以會使用第二個
更詳細的可以看 Function template overloading - cppreference.com

1個讚

很好的解說,感謝回答!

2個讚