2

This follows yesterday's question, where I gave some C++ code that Visual Studio 2013 couldn't handle, and @galop1n kindly provided a workaround, which worked perfectly for that case. But now I've gone a tiny bit further and Visual Studio is giving me grief again.

template <typename T>
using ValueType = typename T::value_type;

template<typename... Containers>
void
foo(const Containers &...args) {
    std::tuple<ValueType<Containers>...> x;
}

template<typename... Containers>
struct Foo {
    std::tuple<ValueType<Containers>...> x;
};

Whenever I try to instantiate either function template foo or class template Foo, I get these two messages:

Test.cpp(21): error C3546: '...' : there are no parameter packs available to expand

and

Test.cpp(21): error C3203: 'ValueType' : unspecialized alias template can't be used as a template argument for template parameter '_Types', expected a real type

In each case (instantiating foo or instantiating Foo), both messages point to the line that defines "x".

UPDATE: My Microsoft bug report now has (in its attachment) all the basic variants of this problem. So that would be the place to watch for a fix.

Community
  • 1
  • 1
slyqualin
  • 297
  • 2
  • 12
  • Man you're just in suck-land, once again, *Both* work flawless on my Mac clang (clang-500.2.79) (based on LLVM 3.3svn). ugh. I don't have my VS2013 up and running so save me some typing and tell me, does VS2013 support template-template parameters? if so, there may be another work-around (at least from me, someone else may have other ideas as well, obviously). Edit: scratch that, not going to work how I wanted. yuck. – WhozCraig Feb 07 '14 at 05:19
  • Maybe using a classic meta-function instead of a type alias might work, e.g. `template struct value_type { typedef typename T::value_type type; };` – pmr Feb 07 '14 at 11:35
  • @pmr, you define "type" with a typedef inside a template class, which is the same way that the containers define "value_type"; so the problem for application code accessing your "type" is essentially the same problem over again, right? – slyqualin Feb 08 '14 at 00:24
  • @slyqualin Yes, you don't get the benefits of `using` declarations and will have to write `typename` all over the place, but it might convince the broken piece of technology you are using to actually let the code compile. – pmr Feb 08 '14 at 00:43
  • @pmr I wouldn't mind writing `typename` all over the place, except that's how I got into trouble in [the first place](http://stackoverflow.com/questions/21607167/dependent-types-with-variadic-templates). – slyqualin Feb 08 '14 at 00:58
  • @slyqualin Yeah, I guess that despite being marketed this way you will simply have to accept that VS2013 does not support variadic templates. – pmr Feb 08 '14 at 01:47

1 Answers1

0

Maybe following works on VS2013 (more verbose :/ ):

template<typename... Containers>
void foo(const Containers &...args) {
    std::tuple<typename std::decay<decltype(*args.begin())>::type...> x;
}

template<typename... Containers>
struct Foo {
    std::tuple<typename std::decay<decltype(*std::declval<Containers>().begin())>::type...> x;
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Thanks for trying, but you see this, like @pmr's solution, repeats the idiom that got me into strife in my [first posting](http://stackoverflow.com/questions/21607167/dependent-types-with-variadic-templates), i.e. it's using an expression of the form `std::tuple`. If VS2013 undestood _that_, then I would have been a happy man long ago. :) – slyqualin Feb 08 '14 at 12:14
  • Btw, the verbosity doesn't worry me, considering that my best workaround so far is to repeat my template for 1 arg, 2 args, 3 args and 4 args. – slyqualin Feb 08 '14 at 12:16