简体   繁体   中英

Template non-type parameter overload

Is it possible to have two template classes with the same name but different non-type template parameters - thus some kind of non-type template parameter overload mechanism?

template <typename T, typename U, void (T::*F)(U)> void common() { ... }
template <typename T, typename U, void (T::*F)(const U &)> void common() { ... }

struct Foo
{
   void foo(bool) {}
}

struct Bar
{
   void bar(const bool &) {}
}

template <typename T, typename U, void (T::*F)(U)> struct Storage 
{
     Storage() { common <T, U, F>(); }
}
template <typename T, typename U, void (T::*F)(const U &)> struct Storage 
{
    Storage() { common <T, U, F>(); }
}

Storage<Foo, bool, &Foo::foo> foo;
Storage<Bar, bool, &Bar::bar> bar;

The reason for having such a mechanism is that both should be able to be created using the same macro.

#define STORAGE(T, U, F) Storage<T, U, F> BOOST_PP_CAT(storage, __LINE__);

STORAGE(Foo, bool, &Foo::foo)
STORAGE(Bar, bool, &Bar::bar)

Thanks for your input!

EDIT

May be some further input is helpful.

What I want to achieve is a method to be run at initialization time. I can provide such a method - or better said two overloaded methods, one with the const-ref and one with the value-member-function-pointer; but to execute them at initilization time I usually would have a stub class (like Storage in this case) which calls this method in its constructor (and so at initialization time, as the STORAGE macro creates an instance of the stub class).

To use the same STORAGE macro I have to have the same template non-type 'overloads' for the stub class I have for the functions to be executed (and I will have to template the class and not the constructor, which I certainly could overload, because it isn't possible to explicitly state constructor template parameters and as the template parameters are non-type I can't have them deduced as well).

EDIT

The pointer to member function has to be a compile-time value (a non-type template parameter) as it will be wrapped in a non-template static method, which then can be stored in a std::vector available at runtime.

It's not entirely clear what problem you're trying to solve. If you're just trying to get your example to work, you can change the 'bool' to 'const bool&'. Does this achieve what you wanted?

template <typename T, typename U, void (T::*F)(U)> void common() {  }

struct Foo
{
    void foo(bool) {}
};

struct Bar
{
    void bar(const bool &) {}
};

template <typename T, typename U, void (T::*F)(U)>
struct Storage 
{
        Storage() { common <T, U, F>(); }
};

Storage<Foo, bool, &Foo::foo> foo;
Storage<Bar, const bool&, &Bar::bar> bar;

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