简体   繁体   中英

How do I initialize an object using a static member function of that object's class?

I have a class with some static functions. The class constructor takes a function as one of its arguments.

template <typename T>
class MyClass {
    public:
        static std::function<T(T, T)> func1 = [](T a, T b) {
            ...
        }

        static std::function<T(T, T)> func2 = [](T a, T b) {
            ...
        }
     
        MyClass(std::function<T(T, T)> func) {
            ...
        }
}

When I initialize an object from this class:

MyClass<int> myObj(MyClass.func1);

The compiler complains that:

> argument list for class template "MyClass" is missing.

What is the correct way to do this while keeping the functions in the class itself?

MyClass is a template not a class. The class that has a static member you want to pass to the constructor is MyClass<int> .

Your code has some typos (missing ; ), I had to add inline for in-class initialization of the static members, I introduced an alias, and for brevity I used struct rather than class (the class has only public members):

#include <iostream>
#include <functional>


template <typename T>
struct MyClass {
    using fun_t = std::function<T(T,T)>;
    static inline fun_t func1 = [](T a, T b) { return a+b; };
    static inline fun_t func2 = [](T a, T b) { return a-b; };
    fun_t fun;
    MyClass(std::function<T(T, T)> func) : fun(func) {}
};

int main() {
    auto x = MyClass<int>{MyClass<int>::func1};
    std::cout << x.fun(1,2);
}

As pointed out in comments by AyxanHaqverdili, this would work as well:

auto x = MyClass{ MyClass<int>::func1 };

due to CTAD (class template argument deduction) where the class templates argument is deduced from the constructors parameters. Live Demo

Also this is fine, although a bit hacky, and I don't recommend to actually use it:

MyClass<int> x { x.func1 }; 

In a nutshell: You can refer to a variable in its own initializer. We aren't doing something that would require x to be fully initialized, so there is no problem with accessing the (already initialized) static member via an instance of MyClass<int> . Live Demo

A less suspicious variant of this suggested by @HTNW is

MyClass<int> x{decltype(x)::func1};

Now it is more obvious that we only use the type of x and access a static member of its class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM