10

I have some code which works under GCC but fails to compile under Visual Studio 2015 (which I realize is in-development but this area I think is supposed to be implemented).

template< typename... T >
class inherit : public T...
{
public:
inherit(T... t) : T(t)... {}
};

int main() {
  auto l1 = []() {};
  auto l2 = []() {};
  inherit<decltype(l1), decltype(l2)> test(l1, l2);
  return 0;
}

That's the code snippet reduced to the pure essence of it. Visual Studio says "syntax error: 'type'" on the constructor of inherit. It then spews a little trace of how it got there and concludes with "you cannot construct an instance of a lambda".

My assumption is that the expansion of T(t)... is not expanding correctly. However I may well be getting the syntax wrong.

EDIT: Sorry the question is: Am I at fault here or not? If so, what is the correct syntax?

ADDITIONAL FINDING: In keeping with the replies I've had, this does seem to be an issue with Visual Studio 2015 having a bug in this area. In testing it seems its the expansion where the constructor params are passed to the lambda base classes which is having the issue. The following test works under VS2015:

template< typename T1, typename T2, typename... T3 >
class inherit2 : public T3...
{
public:
  inherit2(T1 t1, T2 t2) : T1(t1), T2(t2) {}
};

int main() {
  auto l1 = []() {};
  auto l2 = []() {};
  inherit2<decltype(l1), decltype(l2), decltype(l1), decltype(l2)> test(l1, l2);
  return 0;
}
qeadz
  • 1,476
  • 1
  • 9
  • 17
  • 2
    Looks fine, clang++ accepts it as well. What happens when you remove the variadicness, but leave the lambdas in? – dyp Jan 14 '15 at 00:37
  • I think Visual Studio has an issue when you pass a lambda in certain cases https://connect.microsoft.com/VisualStudio/feedback/details/727957/vc11-beta-compiler-fails-to-compile-lambda-key-comparer-for-maps-and-sets http://stackoverflow.com/questions/25777396/passing-my-compar-function-to-stdmultiset-with-c11/25777512#comment43645224_25777512 – AndyG Jan 14 '15 at 01:55
  • 3
    Your code has been supported since gcc 4.6 and clang 3.1 (both from early 2012). Visual C++ is running 3 years behind here. – TemplateRex Jan 14 '15 at 08:37
  • 1
    @dyp the variadics are needed for the failure. After some more messing around it seems to be the T(t)... expansion for passing the parameters to the base constructors which is causing the problem. I'll edit my post with the finding just in case someone else stumbles on this having experienced the same issue. – qeadz Jan 14 '15 at 17:43
  • As an aside, as there is no `using Ts::operator()...;` syntax in C++, you'll have to inherit via a tree or linearly anyhow if you want to make a type that is an "override of lambdas". Btw, you missing `: public T1, public T2` in your "works in VS2015" example? – Yakk - Adam Nevraumont Jun 15 '15 at 16:56
  • @Yakk I don't really recall what I was doing with this now! If I recall the intent was to group them and I was experimenting with using TMP to find the first lambda which would accept the argument. This was all just experimentation - not code in an actual project. The "works in VS2015" was just to show which part couldn't be the variadic. The template instantiation repeats the types so "public T3..." expands to the same as public T1, public T2. – qeadz Jun 15 '15 at 17:37
  • In any case, this whole experiment proved fruitless. I wasn't able to get anything that looked useful out of it. However I did learn some stuff, so theres that! – qeadz Jun 15 '15 at 17:38
  • Using lambdas inheritance-wise, you will want to `using T::operator()` usually, which requires a linear (or tree based) inheritance structure. Then you can "call them all" and let overload resolution sort it out. Otherwise, might as well stuff them into a `std::tuple` if you just need a package of lambdas. – Yakk - Adam Nevraumont Jun 15 '15 at 17:45

1 Answers1

0

It's the compiler. A more recent MSVC, v. 19.00.23106.0 from July 2015, accepts your example as-is.

Perhaps brace initialization syntax T{t}... would have helped. I can't find a suitable online compiler to try, though.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421