c++staticoverloadingnon-static

Overload static templated member function with normal templated member function with different signatures in C++


I have a class MyClass with two simple templated member functions that have the same name test, but one of them is marked as static and their signatures are different:

#include <array>
#include <iostream>

class MyClass
{
public:
    template<std::size_t K>
    static void test(const std::array<int, K>& a)
    {
        std::cout << "static member func called\n";
    }

    template<std::size_t K>
    void test(int x)
    {
        std::cout << "member func called\n";
    }
};


int main()
{
    // MyClass::test<1>({1});        // ill-formed
    MyClass::test<1>(std::array{1}); // static member func called
    MyClass::test<2>({1, 1});        // static member func called
    MyClass{}.test<1>(1);            // member func called
}

Unfortunately, the compiler does not allow me to write MyClass::test<1>({1}); because a call to non-static member function without an object argument occured. Of course, the non-static version would also fit in this case, but since the call is made via the class, the non-static version should not be visible in my opinion. Why does the compiler reject this code?

https://godbolt.org/z/1a6vWxaoj


Solution

  • {1} is int, {1, 1} is an initializer list of two int in the expressions. std::array<int, 1> is an aggregate type. To let the compiler know that you don't want to call the function with int x{1}, use double braces:

    MyClass::test<1>({{1}});
    //                ^^^  encapsulated a's array initializer