c++ - 带有模板参数或类型名的模板函数

标签 c++ templates c++11 c++14

我正在创建一个包含数值数据 vector (可以是 int、float、double 等)的模板类。它有一个操作,调用 std::abs()在数据上。类似于下面的代码。

#include <iostream>
#include <complex>
#include <vector>


template<typename T> class MyData
{
public:
   std::vector<T> data;
   MyData<T> my_abs() const;

};


template<typename T>
MyData<T> MyData<T>::my_abs() const
{
    MyData<T> output;
    output.data.reserve(data.size());
    typename std::vector<T>::const_iterator it;

    for (it = data.begin(); it != data.end(); it++)
    {
        output.data.push_back(std::abs(*it));
    }
    return output;
}


int main()
{
    MyData<double> A;
    A.data = std::vector<double>(10, -1.0);

    MyData<double> test = A.my_abs();

    for (auto el : test.data)
    {
        std::cout << el << std::endl;
    }
    return 0;
}

这适用于 int、float、double 等类型。我还希望能够将此类用于 std::complex<double> 等类型.

环顾四周,我发现我可以使用模板模板参数:

template<template<typename> class T, typename U> class MyData
{
public:
   std::vector<T<U>> data;
   MyData<U> my_abs() const;

};


template<template<typename> class T, typename U>
MyData<U> MyData<T<U>>::my_abs() const
{
    MyData<U> output;
    output.data.reserve(data.size());
    typename std::vector<T<U>>::const_iterator it;

    for (it = data.begin(); it != data.end(); it++)
    {
        output.data.push_back(std::abs(*it));
    }
    return output;
}

前面的代码不起作用,因为我的模板类需要两个参数,

error: wrong number of template arguments (1, should be 2)
MyData<U> abs() const;
       ^

理想情况下,我想要像以前的代码一样的东西。其中my_abs()函数返回传递给我的模板的模板参数的类型。例如,如果我使用 std::complex<double>那么我的主要功能可能类似于:

int main()
{
    MyData<std::complex<double>> A;
    A.data = std::vector<std::complex<double>>(10, std::complex<double>(-1.0, -1.0));

    MyData<double> test = A.my_abs();

    for (auto el : test.data)
    {
        std::cout << el << std::endl;
    }
    return 0;
}

我不确定这是如何实现的(或者是否有可能使用相同的模板类)。

最佳答案

您可以在声明中使用 std::abs(T) 的返回类型。


例子:

#include <iostream>
#include <complex>
#include <vector>
#include <cmath>
#include <utility>

template<typename T> class MyData
{
public:
   std::vector<T> data;
   using abs_type = decltype(std::abs(std::declval<T>()));
   auto my_abs() -> MyData<abs_type> const;
};

template<typename T>
auto MyData<T>::my_abs() -> MyData<abs_type> const
{
    MyData<abs_type> output;
    output.data.reserve(data.size());
    typename std::vector<T>::const_iterator it;

    for (it = data.begin(); it != data.end(); it++)
    {
        output.data.push_back(std::abs(*it));
    }
    return output;
}

int main()
{
    MyData<std::complex<double>> A;
    A.data = std::vector<std::complex<double>>(10, std::complex<double>(-1.0, -1.0));

    auto test = A.my_abs();

    for (auto el : test.data)
    {
        std::cout << el << std::endl;
    }
    return 0;
}

关于c++ - 带有模板参数或类型名的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39774690/

相关文章:

c++ - 具有前向声明类的模板函数

c++ - 虚拟模板?

c++ - 将指针设置为 nullptr 会影响指向同一地址的其他指针吗?

使用 operator= 的 C++ 对象构造

c++ - 模棱两可的模板怪异

c++ - 确定 HWND 是否代表顶级窗口的最佳方法是什么?

c++ - cmake:如何使用静态链接的 boost (或嵌入 boost )创建库

c++ - 在调用删除之前删除动态分配的对象?

C++11:条件编译:成员

c++ - 对异步运行并发出信号的命令使用撤消堆栈