C ++:是否可以创建多类型函数参数?

时间:2019-05-05 19:10:55

标签: c++ function parameters

是否可以使函数fun接受1个参数:数组或向量? 例如,如果我这样做,它将起作用:

我定义了fun(parameter)函数。 parameter可以是std::vector<int>类型,也可以是int*类型。我希望它总结向量/数组中的所有元素。

有点像python函数参数->它可以是任何类型,但我希望它是向量或数组类型。

有可能吗?

3 个答案:

答案 0 :(得分:2)

  

我定义了fun(parameter)函数。参数可以是std::vector<int>类型,也可以是int*类型。我希望它总结向量/数组中的所有元素。

您如何知道仅具有int指针的元素数量?通常的方法是传递一对迭代器。

  

您能给我看一些示例代码,我从没用过白色对吗?

您将迭代器传递到要迭代的范围的第一个元素,并将迭代器传递到最后一个元素之后。在间隔术语中,它是半开[first, last)

#include <array>
#include <vector>
#include <list>
#include <iostream>

template<typename ForwardIterator>
long sum(ForwardIterator first, ForwardIterator last)
{
    long sum{};
    while (first != last)
        sum += *first++;
    return sum;
}

int main()
{
    int foo[]{ 1, 2, 3 };
    std::cout << sum(std::begin(foo), std::end(foo)) << '\n';

    std::array<int, 3> bar{ 1, 2, 3 };
    std::cout << sum(bar.begin(), bar.end()) << '\n';

    std::vector<int> qux{ 1, 2, 3 };
    std::cout << sum(qux.begin(), qux.end()) << '\n';

    std::list<int> hugo{ 1, 2, 3 };
    std::cout << sum(hugo.begin(), hugo.end()) << '\n';
}

哎呀,您也可以只使用一个参数来使用此功能:

#include <array>
#include <vector>
#include <list>
#include <iostream>

template<typename ForwardIterator>
long sum(ForwardIterator first, ForwardIterator last)
{
    long sum{};
    while (first != last)
        sum += *first++;
    return sum;
}

template<typename T>
long sum(T const &container)
{
    return sum(std::begin(container), std::end(container));
}

int main()
{
    int foo[]{ 1, 2, 3 };
    // please note that the array is passed by reference (no pointer):
    std::cout << sum(foo) << '\n';

    // sum(&foo[0]);  // wouldn't work because there is
    // no overload of std::begin() or std::end() for raw pointers

    std::array<int, 3> bar{ 1, 2, 3 };
    std::cout << sum(bar) << '\n';

    std::vector<int> qux{ 1, 2, 3 };
    std::cout << sum(qux) << '\n';

    std::list<int> hugo{ 1, 2, 3 };
    std::cout << sum(hugo) << '\n';
}

当然不要重新发明轮子:std::accumulate

将类型设为正向迭代器的要求是它支持操作iterator++*iterator++。普通指针也可以视为正向迭代器,因为这些操作对指针有效。 LegacyForwardIterator。实际上,指针甚至更强大,并且可以用作随机访问迭代器。 LegacyRandomAccessIterator

但是要解决您的原始问题:除了为不同的参数重载功能或编写函数模板之外,自C ++ 17起,还有std::variant<>

答案 1 :(得分:0)

您必须使用相同的名称但使用不同的参数来重写该函数,这称为函数重载,将其检出。

答案 2 :(得分:0)

无需重新发明轮子:C ++标准库具有恰好用于此目的的功能:std::accumulate()。它使用两个迭代器参数并返回元素的总和(您还可以提供第三个参数,该参数定义您自己的加法运算符版本,允许进行任何类型的累加运算):

#include <array>
#include <vector>
#include <list>
#include <numeric>
#include <iostream>

int main()
{
    int foo[]{ 1, 2, 3 };
    std::cout << std::accumulate(std::begin(foo), std::end(foo)) << '\n';

    std::array<int, 3> bar{ 1, 2, 3 };
    std::cout << std::accumulate(bar.begin(), bar.end()) << '\n';

    std::vector<int> qux{ 1, 2, 3 };
    std::cout << std::accumulate(qux.begin(), qux.end()) << '\n';

    std::list<int> hugo{ 1, 2, 3 };
    std::cout << std::accumulate(hugo.begin(), hugo.end()) << '\n';
}