This question is in spirit a follow-on from this question from another user, which has some excellent answers: Is it possible to write a template to check for a function's existence?
I want to do exactly what is described in this question, except I want to be able to do it for a constructor. Eg, given these two types:
class NormalType
{
public:
NormalType()
{
std::cout << "NormalType::NormalType()" << std::endl;
}
};
class SpecialType
{
public:
SpecialType()
{
std::cout << "SpecialType::SpecialType()" << std::endl;
}
SpecialType(int someArg)
{
std::cout << "SpecialType::SpecialType(int someArg)" << std::endl;
}
};
And this helper function for constructing an object:
template<class T>
class ConstructHelper
{
public:
template<bool HasSpecialConstructor>
static T Construct()
{
return T();
}
template<>
static T Construct<true>()
{
return T(int(42));
}
};
I want to be able to write code like this:
NormalType normalType = ConstructHelper<NormalType>::Construct<has_special_constructor<NormalType>::value>();
SpecialType specialType = ConstructHelper<SpecialType>::Construct<has_special_constructor<SpecialType>::value>();
Where the desired results are that NormalType::NormalType()
is called, and SpecialType::SpecialType(int someArg)
is called. The missing ingredient here is that critical has_special_constructor
helper, which can determine if our special constructor exists for a given type.
The previous question I referenced deals with checking if a given function exists on a type, and there were a variety of working solutions presented. Unfortunately, most of them rely on being able to take the address of the target method, and as per the C++ spec, you can't take the address of a constructor (12.1.10). Of the remaining working solutions, all of them seem to rely on SFINAE with decltype on an arbitrary expression in a template specialization. That is a simple way to solve this problem, but unfortunately I'm working on Visual Studio 2013, which doesn't properly support the C++11 SFINAE rules, and still won't with the release of "Visual Studio 14" either. With proper SFINAE support, I should be able to do this for example:
template<class T>
struct has_special_constructor
{
template<class S>
struct calculate_value: std::false_type {};
template<>
struct calculate_value<decltype(T(int(42)))>: std::true_type {};
static const bool value = calculate_value<T>::value;
};
But that won't compile under VS2013 if I try and test a type that doesn't define my target constructor, due to the lack of SFINAE support. That said, I'm not yet convinced this is impossible, I think there might be a way to make it work, but I haven't been able to find a solution so far. Anyone out there see a way to do this that I've overlooked?
Here's some more info about what I'd need in order to accept an answer as a solution to this problem:
It must be possible to resolve has_special_constructor<T>::value
for any given type without additional code being written for that specific type.
I'm primarily targeting Visual Studio 2013, so any solution must work in that environment. I know a fully conforming C++11 compiler could manage this problem more easily, but I'm looking for something that can function now on my current target compiler.
If anyone can supply a solution that works in a C++03 compiler (IE, without any C++11 features) I'll accept that over one that uses C++11 features.
I'd settle for a MSVC extension-based workaround at this point, since I can use the preprocessor to fall back to this method until full C++11 support comes along.
As long as you are satisfied with automatic type inference, you can use a template constructor (of a non-template class). @updogliu: Absolutely. But, the question is asking about "a template constructor with no arguments" If there are no function arguments, no template arguments may be deduced.
The main type of templates that can be implemented in C are static templates. Static templates are created at compile time and do not perform runtime checks on sizes, because they shift that responsibility to the compiler.
Function templates are similar to class templates but define a family of functions. With function templates, you can specify a set of functions that are based on the same code but act on different types or classes. The following function template swaps two items: C++ Copy.
Class Template Declarationtemplate <class T> class className { private: T var; ... .. ... public: T functionName(T arg); ... .. ... }; In the above declaration, T is the template argument which is a placeholder for the data type used, and class is a keyword.
template<class T>
using has_special_constructor = std::is_constructible<T, int>;
Possible "C++03" version:
template <class T>
struct has_special_constructor {
typedef char one;
typedef struct { char _[2];} two;
template <std::size_t>
struct dummy {};
template<class U>
static one f(dummy<sizeof(U(42))>*);
template<class>
static two f(...);
static const bool value = sizeof(f<T>(0)) == sizeof(one);
};
This works on g++ 4.4 or later in C++03 mode. I put "C++03" is in scary quotes since this depends on expression SFINAE, which seems to be a bit of a gray area in C++03 - apparently C++03's wording seemed to allow it, but no major compiler vendor actually supported it until C++11 is almost here (GCC 4.4 was released in 2009), so it's arguable whether "pure" C++03 allows it...
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