I’m going out on a limb here, assuming that it is possible but I’m not quite sure. Basically what I’m looking for is a way to switch at compile-time between using a default constructor or a constructor that takes one argument by reference.
i.e.
T* create<T>()
{
return new T(1); // if possible
}
T* create<T>()
{
return new T(); // fallback to here
}
I’m using the VS2010 compiler and it does not support std::is_constructible but I can use decltype.
I went digging in the VS2012 type_traits header and looked at the std::is_constructible implementation and well I got a bit turned around. I don’t get it how people write code that way. The headers are the most convoluted piece of code I’ve ever seen. Anyway, I saw that it was using decltype and it got me think, hopefully someone with more experienced can provide me with an answer.
After going through @ipc’s answer I’ve settled on the following code
// std::declval is not supported by VS2010
template <typename T> typename std::add_rvalue_reference<T>::type declval();
template <class T, class R0>
decltype(new T(declval<R0>()))
createInstance_(R0& r0, int = 0)
{
return new T(r0);
}
template <class T, class R0>
T*
createInstance_(R0&, ...)
{
return new T();
}
The above code will work but it does confuse the IntelliSense Engine, anyway I thought it was nice that you could omit the extra function by simply using a default argument. I’ve tested this code with VS 2010 and it compiles fine and runs as expected.
I have no VS2010 to check if it compiles there, but the following matches your example.
Output: