KDAlgorithms icon indicating copy to clipboard operation
KDAlgorithms copied to clipboard

Do not use variadic type parameters in templates

Open dangelog opened this issue 3 years ago • 1 comments

A container's type may include non-type template parameters, e.g.

QVarLengthArray<int, 32> container;
                  // ^^ NTTP

Accepting them with template <typename ...> typename Container will therefore fail:

    QVector<int> vec{1, 2, 3, 4};
    const auto toString = [](int i) { return QString::number(i); };
    auto result = KDAlgorithms::transformed<QVarLengthArray>(vec, toString); // ERROR

For some reason this was a deliberate choice. But why simply using template <typename> typename Container doesn't work here?

dangelog avatar Sep 08 '22 08:09 dangelog

Further investigation shows that template <template <typename> class X> can match something like e.g. std::vector only since C++17:

https://cplusplus.github.io/CWG/issues/150.html https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0522r0.html

The suggestion therefore would be to have

  • the variadic version in C++14
  • the non-variadic one in C++17

maybe using a macro or so.

Possible cross-test:

// C++17 only, since QVLA has a non-type template parameter
void TestAlgorithms::transformedChangeContainerAndDataType3()
{
    QVector<int> vec{1, 2, 3, 4};
    const auto toString = [](int i) { return QString::number(i); };
    auto result = KDAlgorithms::transformed<QVarLengthArray>(vec, toString);
    QVarLengthArray<QString> expected{"1", "2", "3", "4"};
    QCOMPARE(result, expected);
}

dangelog avatar Sep 09 '22 14:09 dangelog