Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Default) construct an object for every variadic type

Consider this code snippet:

void Foo(std::string str1, std::string str2) {}

template<typename... Types>
void Bar()
{
    Foo(Types{}...); // wont compile
}

Bar<std::string, std::string>();

What I want to do here is to default construct two std::string objects inside the Bar method and pass them to Foo. However my vain attempts (one of them being in the snippet) wont compile so I am wondering whether this is even possible.

I compiled with VC 2013, which throws compiler errors at me. As stated in the comments, other compilers can handle it. Can anyone tell whether the above snippet is standard conform?

like image 800
Sebastian Hoffmann Avatar asked Feb 06 '14 19:02

Sebastian Hoffmann


1 Answers

It's a problem in the MSVC variadic template expansion process; when it unpacks the list of types it fails to recognise them as suitable for a constructor call. As a workaround, you can perform a type transformation to force the compiler to recognise them:

template<typename T> using identity_t = T;  // NEW CODE

void Foo(int, int);

template<typename... Types>
void Bar()
{
    Foo(identity_t<Types>{}...);  // use identity type transformation
}

int main() {
    Bar<int, int>();
}

I haven't managed to find an issue number yet.

like image 149
ecatmur Avatar answered Sep 24 '22 07:09

ecatmur