Consider the following simplified C++ code:
template <typename ... TEventArgs>
struct Event
{
// ...
};
template <typename T>
struct Parameter
{
using Type = T;
// ...
};
template <typename ... Parameters>
struct Command
{
Event<typename Parameters::Type...> Invoked;
};
int main()
{
Command<Parameter<int>, Parameter<float>> c;
}
The Visual Studio C++ compiler (November 2013 CTP, Visual Studio 2013 Update 1) produces the following error: source.cpp(17): error C3546: '...' : there are no parameter packs available to expand
Mingw 4.8.1. on the other hand compiles the code without any problems. Apparently, the Visual Studio compiler has a bug that prevents it from expanding the parameter pack when the expression involves accessing a type of the variadic parameters. Other expansions work, though. For instance, Event<std::vector<Parameters>...> Invoked;
compiles successfully or you could even successfully access static members to call a variadic function like this in Command
's constructor: SomeVariadicFunc(Parameters::SomeStaticFunc()...);
.
So, the questions are:
1) Which compiler is wrong: Visual Studio or mingw? Although I don't see anything that would prevent the typename Parameters::Type
parameter pack expansion from working, I'm not 100% sure it's valid C++.
2) Is there a work around? Basically, I would have to perform a projection from a "sequence" of Parameters
to a "sequence" of Parameters::Type
. Is that possible? I tried to construct that list using a recursive struct but I could only come up with something like myStruct<type1, mystruct<type2, mystruct<type3, ...>>>
, which is not what I need.
Thank you for your help.
Yakk was able to come up with a workaround for the problem in the comments above. The final version that compiles perfectly with both Visual Studio an mingw is the following:
template <typename ... TEventArgs>
struct Event
{
// ...
};
template <typename T>
struct Parameter
{
using Type = T;
// ...
};
template <typename ... Parameters>
struct Command
{
private:
// Workaround for the Visual Studio bug
template<typename T> struct ExpandArgs
{
typedef typename T::Type Type;
};
public:
Event<typename ExpandArgs<Parameters>::Type...> Invoked;
};
int main()
{
Command<Parameter<int>, Parameter<float>> c;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With