Parameter induction with std::variant

std::variant
std::variant get
std::get_if
std::variant visit
std::variant overhead
std variant get if
std::variant implementation
std::variant vs union

Recenty I am working on an ORM which accepts registration of functions by doing the following:

orm->register_func("NAME", &User::set_name);

So basically when the database returns the column NAME, the ORM will use the function set_name in User. During the development I learned more about std::variant and here is a little example of how I use it:

template<typename RET, typename T, typename ...Args>
using FPTR = RET(T::*)(Args...);

template<typename T>
using VARIANT_FPTR = std::variant<FPTR<void, T, const char *>, FPTR<void, T, const unsigned int>, long int>;

FPTR is basically a generic function pointer (assuming that the function is a class member) and VARIANT_FPTR defines the possibilities of functions I can register in the ORM.

Now, I have a problem due to the std::variant type. Here is the register_func implementation:

void register_func(std::string name, VARIANT_FPTR<T> ptr)
{
   _map.insert(std::make_pair(name, ptr));
}

However, I get a compilation error since a parameter like &User::set_name is not of type std::variant.

Is there a way to make the register_func induce the type of its parameter? If not is there another way to make a similar process?

The compilation error is:

error: cannot convert ‘<unresolved overloaded function type>’ to ‘VARIANT_FPTR<services::User>’ {aka ‘std::variant<void (services::User::*)(const char*), void (services::User::*)(unsigned int), long int>’}

Here is the map definition:

template<typename T>  class Orm
{
private:
   std::map<std::string, VARIANT_FPTR<T>> _map;
   // ...
};

You need to provide the exact type in the instantiation of the std::map template. For instance, if you need User 's member functions in it, you need the following:

std::map<std::string, VARIANT_FPTR<User>> _map;
//                                 ^^^^^

Following is a complete minimal working example: See live online

#include <iostream>
#include <variant>
#include <string>
#include <map>

struct User
{
    template<typename T>
    void set_name(T)
    {}
};

template<typename RET, typename T, typename ...Args>
using FPTR = RET(T::*)(Args...);

template<typename T>
using VARIANT_FPTR = std::variant<FPTR<void, T, const char*>, FPTR<void, T, const unsigned int>, long int>;


template<typename T> class Orm
{
private:
    std::map<std::string, VARIANT_FPTR<T>> _map;

public:
    void register_func(std::string name, VARIANT_FPTR<User> ptr)
    {
        _map.emplace(name, ptr);
    }
};

int main()
{
    Orm<User> orm{};
    orm.register_func("NAME", &User::set_name<const char*>);
    orm.register_func("NAME", &User::set_name<const unsigned int>);
    return 0;
}

std::variant, An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no� template<typename T = std::variant<int,double,float>> void f() { } Is it possible to somehow retrieve the std::variant parameter pack as a variadic template argument(or other means)? I need to get a list of types I could run a fold expression on, so for the example above I would need something like a typename

The issue (assuming that the compiler is correct in saying that the member function in question is overloaded) is that std::variant<X,Y> does not have constructors accepting X and Y. Instead, it has a constructor template that performs overload resolution to determine which alternative to construct. That template cannot deduce a simple T from a pointer (or pointer-to-member) to an unknown member of an an overload set. In the case where only one of the overloads is suitable for any of the variant’s choices, you can simply provide those overloads yourself:

template<class T>
auto pick(FPTR<void, T, const char *> f) {return f;}
auto pick(FPTR<void, T, const unsigned int> f) {return f;}

/* elsewhere */ {
  orm->register_func("NAME", pick(&User::set_name));
}

If that’s still ambiguous, you can use static_cast to choose the overload:

orm->register_func
  ("NAME",
   static_cast<FPTR<void, T, const char *>>
     (&User::set_name));

A linear parameter variant H∞ control design for an induction motor , The standard setup of the H∞ control problem consists of finding a static or Speed sensorless linear parameter variant H∞ control of the induction motor. Empty variants are also ill-formed (std:: variant < std:: monostate > can be used instead). A variant is permitted to hold the same type more than once, and to hold differently cv-qualified versions of the same type.

Apparently parameter induction with std::variant is not always feasible in this kind of tricky case. So to solve this problem I finally decided to make the usage of register function a little bit more verbose. Here it is:

template<typename RES, typename CLASS, typename ...Args>
void register_func(std::string name, FPTR<RES, CLASS, Args...> ptr) {
   _map.insert(std::make_pair(name, ptr));
}

thus to use it you need to write:

orm->register_func<void, Class, const char *>("name", &Class::set_name);
Interesting fact

I found out that some of the parameter can actually be inducted in some cases. In the case of the following function:

void Class::set_id(unsigned long id)

I apparently can just call the register_function like this:

orm->register_func("id", &Class::set_id);

Tactics — Coq 8.12.0 documentation - The Coq Proof Assistant, Variant eexact term. � Inductive contains0 : list nat -> Prop := | in_hd : forall l, contains0 (0 :: l) | in_tl : forall l b, contains0 l -> contains0 (b :: l). contains0 is� This paper focuses on an analysis of tool wear and optimum machining parameter in the induction assisted milling of Inconel 718 using high heat coated carbide and uncoated carbide tools. Thermally assisted machining is an effective machining method for difficult-to-cut materials such as nickel-based …

[PDF] The Impact That Voltage Variations Have on AC Induction , standard as the benchmark for acceptable performance and variations. Introduction. Motor reliability rated load with a variation in the voltage or the frequency up to the following: • Plus or minus 10 percent ::e 10,000 xl.l.I. l.l.I c.:> . � ffi. >-. � 100. 60. 80. 100. 120. 140. 160. 180. 200. 220. 240 Parameter. UnbaI~. Unbal. Similar to a DC motor, a 3Φ AC Induction motor can be mathematically modeled as an electrical and a mechanical system related by back-emf to speed and current-torque relationships. In this experiment, the electrical and mechanical parameters of the Induction motor are determined.

[PDF] Estimating Parameters of the Induction Machine by the , From the variation of impedance to the rotor speed, the parameters of the parameter estimation in off-line estimation is the IEEE standard 112� However, for a squirrel cage induction motor, this model does not satisfy the conditions of exact calculations. Parameter determination of an equivalent circuit for a squirrel cage induction motor is a complex problem, because no reliable theory exists and no methods of direct measurements in a rotor circuit are available.

Assigning function to natural allelic variation via dynamic , Natural variation in GAL3 affects the dynamics of network induction Error bars represent standard error of the mean (n=6). the function mixtools:: normalmixEM() , iii) these parameters were used to determine t such as. I.e. have more, than one parameter. Or what I should to do if two different variant's underlying types have ambiguous constructor prototypes? In my opinion, this is the defect of implementation of the boost::variant library in the light of the new features of C++11 standard, if any at all can be applyed to solve the problem.

Comments
  • Can you give an example of how you are calling the register_func, and what is the exact error that you are getting? You may need to explicitly construct the variant like this: VARIANT_FPTR<T>(&User::set_name)
  • I call the register_func exactly as I show on the first piece of code and I edit the post to show the error.
  • @ClémentJean Then you can write a helper template function to get the correct overload from the class. Like this: godbolt.org/z/4T3T4g. And here is the example code without the test: godbolt.org/z/-MArdf. If that's solved the issue, I can update the answer with that!
  • Just to confirm the significance of the error message, User::set_name is overloaded, right?
  • @ClémentJean: No—I said "overloaded", like GCC did.
  • The map is actually in a generic class providing this T, so do I still need to do that ?