mercredi 25 février 2015

Template specialization and SFINAE on VS2013

I'm using VS2013 (update 4), and I'm having trouble compiling the following variadic template code:



#include <iostream>
#include <string>

// Variadic template "multiwrite" for writing a string to multiple different streams
template <typename T>
void mwrite(T value, std::ostream& os) { os << value; }
template <typename T, typename... SS>
void mwrite(T value, std::ostream& os, SS... streams) { mwrite(value, os); mwrite(value, streams...); }

// Main
int main()
{
std::ostream& out = std::cout;
std::ostream& err = std::cerr;
mwrite(std::string("Hello"), out, err);
return 0;
}


The compiler error I get is:



error C2280: 'std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const std::basic_ostream<char,std::char_traits<char>> &)' : attempting to reference a deleted function
see declaration of 'std::basic_ostream<char,std::char_traits<char>>::basic_ostream'


I have tried implementing this function with other types than std::ostreams and those work fine. Also, I know about the fact that ostreams don't have a copy-constructor, and at first I suspected that that was the problem here.


However, then I tried explicitly specifying the template parameters at the call point in main:



mwrite<std::string, std::ostream&>(std::string("Hello"), out, err);


and this works fine as well. So, I find myself in the situation that the compiler fails on a particular specialization (the one with pass-by-value ostreams), whereas there does exist a specialization that is perfectly legal (with pass-by-reference ostreams). I am reluctant to blame the compiler, so my question is: is this behavior somehow still SFINAE-conforming? Am I misunderstanding something here?


Aucun commentaire:

Enregistrer un commentaire