0

I am trying to create class deriving from variadic template. Here is the code:

struct Some { };

template < class Base, class T >
struct Feature
{
protected:
    void DoStuff(T& t) { }
};

template < class T, class ... Ts >
struct MultiFeature
    : public Feature< T, Ts >...
{

};

class TestFeature
    : public MultiFeature< Some, std::int16_t, std::string >
{
public:
    void TestDoStuff()
    {
        std::int16_t i;
        DoStuff(i);
    }
};

Feature should be a simple wrapper around some basic type (in this case, integer and string), providing some functionality to class deriving from it. MultiFeature is used so that I do not have to derive from Feature< std::int16_t >, Feature< std::string >.

As far as I understand, there should be no ambiguity in this case, because there are two different DoStuff functions, each taking different parameter type, however VS2017 complains about ambiguous access. Is this correct behavior? If so, is there any simple workaround around this problem?

EDIT

It seems that compiler is right here, however in this answer, suggested workaround for this is to bring base class member functions into scope with using (Ambiguous access to base class template member function). Is it somehow possible to do this for variadic template base class?

3
  • if you can use C++17, using Feature<Ts>::doStuff...;; otherwise (pre C++17) the best I can imagine use recursion Commented Jun 6, 2019 at 19:04
  • Thanks, this is what I needed, I didn't know that you can expand template pack in this context. Commented Jun 6, 2019 at 19:07
  • "I didn't know that you can expand template pack in this context." - It's a new C++17 feature. Commented Jun 6, 2019 at 19:12

1 Answer 1

0

It seems that compiler is right here, however in this answer, suggested workaround for this is to bring base class member functions into scope with using (Ambiguous access to base class template member function). Is it somehow possible to do this for variadic template base class?

If you can use C++17, it's trivially simple

template <typename T, typename ... Ts>
struct MultiFeature : public Feature<T, Ts>...
 {
   using Feature<T, Ts>::DoStuff...;
 };

Unfortunately the variadic using is introduced in C++17 so, in C++11 and C++14, the best I can imagine is a MultiFeature recursive definition

// ground case: a fake DoStuff to abilitate following using
template <typename T, typename ... Ts>
struct MultiFeature
 { void DoStuff () { } };

// recursion case
template <typename T, typename T0, typename ... Ts>
struct MultiFeature<T, T0, Ts...>
   : public Feature<T, T0>, public MultiFeature<T, Ts...>
 {
   using Feature<T, T0>::DoStuff;
   using MultiFeature<T, Ts...>::DoStuff;
 };

The following is a full compiling example (with both cases)

struct Some { };

template <typename, typename T>
struct Feature
 {
   protected:
      void DoStuff (T &) { }
 };

#if 0
template <typename T, typename ... Ts>
struct MultiFeature : public Feature<T, Ts>...
 {
   using Feature<T, Ts>::DoStuff...;
 };
#else
// ground case: a fake DoStuff to abilitate following using
template <typename T, typename ... Ts>
struct MultiFeature
 { void DoStuff () { } };

// recursion case
template <typename T, typename T0, typename ... Ts>
struct MultiFeature<T, T0, Ts...>
   : public Feature<T, T0>, public MultiFeature<T, Ts...>
 {
   using Feature<T, T0>::DoStuff;
   using MultiFeature<T, Ts...>::DoStuff;
 };
#endif

struct TestFeature
   : public MultiFeature<Some, short, int, long, long long>
 {
   void TestDoStuff ()
    { int a{}; DoStuff(a); }
 };


int main ()
 {
   TestFeature tf;
 }
Sign up to request clarification or add additional context in comments.

2 Comments

I updated my VS2017 to latest update, checked existence of __cpp_variadic_using and tried it the simple way (tried both std:c++17 and std:c++latest), yet it still complains that "Ts must be expanded in this context". Is this compiler bug?
@AlexanderBily - Not sure but I suspect that your MSVC 2017 is too old for this feature. By example, according this page wasn't supported in version 15.6. I can only confirm that compile with both g++ (8.3.0) and clang++ (7.0.1).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.