简体   繁体   中英

C++ variadic class templates and member functions

I'm having problems working around a problem in the following code...

#include <functional>

template<typename... ARGS>
class MyClass {
public :
    void function(ARGS... args)
    {
    }
};

int main(int argc, char * argv[])
{
    MyClass<int>        myClassInt;      // works fine
    MyClass<int, float> myClassIntFloat; // works fine
    MyClass<void>       myClassVoid;     // <---- won't compile

    return 0;
}

Clang quite rightly refusing to compile this if I instantiate MyClass on void , complaining that MyClass<void>::function is not a legal definition. However the real class I have needs to be able to instantiate this kind of thing on a void. I've been staring at this for ages and I'm stuck as to what template SFINAE jiggery-pokery I need to get around it.

Either use MyClass<> at point of use, or this hack:

template<typename... ARGS>
class MyClass {
public :
  void function(ARGS... args)
  {}
};
template<>
class MyClass<void>:public MyClass<> {
public :
  using MyClass<>::MyClass; // inherit ctors
};

There may also be other things you need to do in MyClass<void> to act as a relatively transparent proxy to MyClass<> .

We can avoid those issues by not using MyClass directly.

template<typename... ARGS>
class MyClass_t {
public :
  void function(ARGS... args)
  {}
};

template<class...Args>
struct MyClass_helper {
  using type=MyClass_t<Args...>;
};
template<>
struct MyClass_helper<void>:MyClass_helper<> {};
template<class...Args>
using MyClass=typename MyClass_helper<Args...>::type;

now, MyClass<void> expands to MyClass_t<> , and MyClass<int, float> expands to MyClass_t<int,float> .

We don't directly use MyClass_t , instead we name it via MyClass<...> . The downside to this technique is that MyClass<???> if used as a function argument is a non-deduced context; so you have to use MyClass_t<???> instead in those cases, and they won't see the void .

My preferred solution is to just use MyClass<> directly instead of MyClass<void> .

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