I have a templated class named check and its partial specialization, now i am publically inheriting a class named childcheck from the partial specialization of the class check. but compiler gives following error message
no matching function for call to `check::check()'
candidates are: check::check(const check&)
check::check(t*) [with t = int*]
look at the code and explain the reason please
#include<iostream.h>
template<class t>
class check
{
t object;
public:
check(t);
};
//defining the constructor
template<class t>
check<t>::check<t>(t element)
{
cout<<"general templated class constructor"<<endl;
}
//partial specialization
template<class t>
class check<t*>
{
t* object;
public:
check(t*);
};
template<class t>
check<t*>::check<t*>(t* element)
{
cout<<"partial specialization constructor"<<endl;
}
//childcheck class which is derived from the partial specialization
template<class t>
class childcheck:public check<t*>//inheriting from the partial specialization
{
t object;
public:
childcheck(t);
};
template<class t>
childcheck<t>::childcheck<t>(t element):check<t>(element)
{
cout<<"child class constructor"<<endl;
}
main()
{
int x=2;
int*ptr=&x;
childcheck<int*>object(ptr);
cout<<endl;
system("pause");
}
You inherit from check<t*> yet call a base class constructor check<t> as if you inherited from check<t>. Which check<> do you want to inherit from?
I believe that what you really want do is this:
template<class t>
class childcheck:public check<t>
If t is int*, then childcheck<int*> will inherit from check<int*> which is fine. The rest of your code can remain the way it is in the original question.
Read about Template Partial Specialization at cprogramming.com, it explains
your previous question.
Related
While trying to get some old software to compile with clang, I encountered some code similar to the following:
class OuterClass {
private:
template <class T>
class InnerClass {};
};
template <class T>
class OtherClass {};
template <class T>
class OtherClass<OuterClass::InnerClass<T>> {};
My understanding of this code is that the template class OtherClass is specialized for instantiations of the private inner template class OuterClass::InnerClass.
g++-10 (version 10.2.0) seems to compile this code without any errors or warnings, but clang++-10 (version 10.0.0) complains that "'InnerClass' is a private member of 'OuterClass'" at the template specialization.
Of course, I could make InnerClass public, but, since InnerClass is private in the original code, I think this solution would not be ideal. Is there a way I could allow InnerClass to be used in the specialization of OtherClass only (perhaps with some clever use of friend)?
I thought maybe I could do something like this, (which is similar to the approach taken in this answer to a similar question but I get an error stating that "partial specialization cannot be declared as a friend."
template <typename T>
friend class OtherClass<InnerClass<T>>;
The posted code appears to compile under gcc only because the template is never actually instantiated (and no code is generated), but fails if attempting to instantiate it.
For OtherClass<InnerClass<T>> instantiations to work, the inner type needs to be made accessible to the template classes. One way to do it is by declaring those as a public type in OuterClass.
#include <iostream>
template <class T>
class OtherClass;
class OuterClass {
private:
template <class T>
class InnerClass { };
public:
template <class T>
using OtherInner = OtherClass<InnerClass<T>>;
};
template <class T>
class OtherClass {
public:
OtherClass() { std::cout << "other<T>" << std::endl; }
};
template <class T>
class OtherClass<OuterClass::InnerClass<T>> {
public:
OtherClass() { std::cout << "other<inner>" << std::endl; }
};
int main() {
OtherClass<char> a; // output: other<T>
OuterClass::OtherInner<int> b; // output: other<inner>
// OtherClass<OuterClass::InnerClass<A>> c; // error: InnerClass is private
}
The above assumes that OuterClass knows about the OtherClass templates that it wants to expose InnerClass to. Probably a reasonable assumption in the context, otherwise InnerClass could simply be made public and accessible to all other classes/templates indiscriminately.
I have a templated class with an templated member function
template<class T>
class A {
public:
template<class CT>
CT function();
};
Now I want to specialize the templated member function in 2 ways. First for having the same type as the class:
template<class T>
template<> // Line gcc gives an error for, see below
T A<T>::function<T>() {
return (T)0.0;
}
Second for type bool:
template<class T>
template<>
bool A<T>::function<bool>() {
return false;
}
Here is how I am trying to test it:
int main() {
A<double> a;
bool b = a.function<bool>();
double d = a.function<double>();
}
Now gcc gives me for the line marked above:
error: invalid explicit specialization before ‘>’ token
error: enclosing class templates are not explicitly specialize
So gcc is telling me, that I have to specialize A, if I want to specialize function, right?
I do not want to do that, I want the type of the outer class to be open ...
Is the final answer: it is not possible? Or is there a way?
Yes, this is the problem:
error: enclosing class templates are not explicitly specialized
You cannot specialize a member without also specializing the class.
What you can do is put the code from function in a separate class and specialize that, much like basic_string depends on a separate char_traits class. Then then non-specialized function can call a helper in the traits class.
You can use overload, if you change the implementation.
template <typename T>
class Foo
{
public:
template <typename CT>
CT function() { return helper((CT*)0); }
private:
template <typename CT>
CT helper(CT*);
T helper(T*) { return (T)0.0; }
bool helper(bool*) { return false; }
};
Simple and easy :)
Why the *this of the derived<T> class is still of base<T> type?
I thought the typename X would take care of that.
If this looks ugly, what is a better way?
Failed Attempt:
template <typename T>
class Derived;
template <typename T, typename X>
class Base{
public:
T val;
X f(void){
return *this;
}
};
template <typename T>
class Derived: public Base<T, Derived<T> >{
};
int main(void){
Derived<int> B;
Derived<int> C = B.f();
}
Error:
test4.cpp(9): error: no suitable user-defined conversion from "Base<int, Derived<int>>" to "Derived<int>" exists
return *this;
^
detected during instantiation of "X Base<T, X>::f() [with T=int, X=Derived<int>]" at line 20
compilation aborted for test4.cpp (code 2)
You may do the downcast with:
X f(){ return static_cast<X&>(*this);}
When the compiler looks at class Base<int, Derived<int>> it has no reason to believe that there is actually a Derived<int> that inherited from it. One could do class Other : public Base<T, Derived<T>>{} and the conversion from class Base<int, Derived<int>> to Derived<int> would be incorrect, so an automatic conversion is not allowed.
If you make a rule that says that the second template parameter must be the derived type that inherits that base (which class Other violates) you can bypass the type system with a cast, but make sure the rule is not violated.
You have
X f(void){
return *this;
}
In this function, type of *this is still the base class type. There is no automatic conversion from the base type to X.
I am unable to suggest a clean solution since X can be anything at that point, not necessarily Derived<T>.
I can use:
template <typename T>
class Derived2 : public Base<T, double>
{
};
How's the base class supposed to deal with that?
The approach used in f() seems to be a design flaw.
Update
If Derived is guaranteed to have the form
template <typename T>
class Derived : public Base<T, Derived<T>>
{
};
Then, you can use:
X& f(void){
return static_cast<X&>(*this);
}
Please note that I changed the return type from X to X&. It avoids the cost of making a copy every time you call the function.
First of all, I would modify Base so that it accepts only one template parameter.
This way, it matches exactly the common form shown for the CRTP idiom.
Actually, it seems to me that there is no reason to use both T and Derived<T> as a template parameter in this case, for the latter already contains the former and T, Derived<T> is the pattern to which you want to adhere:
template<typename>
class Base;
template <typename T, template<typename> typename X>
class Base<X<T>> {
// ...
};
template <typename T>
class Derived: public Base<Derived<T>>{
// ....
};
Then you can use a promotion from the bottom as mentioned by #Jarod42:
X<T> f(void) {
return *static_cast<X<T>*>(this);
}
Note that here you are making systematically a copy of the object and probably it is not what you want.
Another option is to modify a bit the architecture and use a covariant return type (it follows a minimal, working example):
template <typename T>
class Base {
T val;
public:
virtual const Base<T>& f(void) const {
return *this;
}
};
template <typename T>
class Derived: public Base<T> {
public:
virtual const Derived<T>& f(void) const {
return *this;
}
};
int main(void) {
Derived<int> B;
Derived<int> C = B.f();
}
Which one is better for you mostly depends on the actual problem.
I have such class
template<typename T>
class ConnectionStatus:
{
public:
virtual void setStatus(const T& status) = 0;
virtual T getStatus() = 0;
};
And i want to have a reference to this class in another class, so i do this: ConnectionStatus<typename T>& status; but compiler said error: template argument 1 is invalid. So how i can make a refernce to template virtual class?
Thank you for any help.
There are two main possibilities: when you know what that template argument should be for your class and when you don't.
For the former, it's a simple case of providing it (say it's int in this case):
struct MyClass
{
ConnectionStatus<int> &m_connection_status;
};
If you don't know the argument, make your class a template class:
template <typename ConnectionStatusType>
struct MyClass
{
ConnectionStatus<ConnectionStatusType> &m_connection_status;
};
I have a templatized class like so :
template<typename T>
class A
{
protected:
std::vector<T> myVector;
public:
/*
constructors + a bunch of member functions here
*/
}
I would like to add just ONE member function that would work only for 1 given type of T. Is it possible to do that at all without having to specialize the class and reimplement all the other already existing methods?
Thanks
The simplest and cleanest solution is to use a static_assert() in the body of a method, rejecting other types than the selected one (in the below example only integers are accepted):
#include <type_traits>
#include <vector>
template <typename T>
class A
{
public:
void onlyForInts(T t)
{
static_assert(std::is_same<T, int>::value, "Works only with ints!");
}
protected:
std::vector<T> myVector;
};
int main()
{
A<int> i;
i.onlyForInts(1); // works !
A<float> f;
//f.onlyForInts(3.14f); // does not compile !
}
OK CASE DEMO
NOK CASE DEMO
This utilizes the fact that a compiler instantiates a member function of a class template only when one is actually used (not when the class template is instantiated itself). And with the above solution, when a compiler tries to do so, it fails due to the execution of a static_assert.
C++ Standard Reference:
§ 14.7.1 Implicit instantiation [temp.inst]
Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist. Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a class template is implicitly instantiated when the function is called in a context that requires the value of the default argument.
[ Example:
template<class T> struct Z {
void f();
void g();
};
void h() {
Z<int> a; // instantiation of class Z<int> required
Z<char>* p; // instantiation of class Z<char> not required
Z<double>* q; // instantiation of class Z<double> not required
a.f(); // instantiation of Z<int>::f() required
p->g(); // instantiation of class Z<char> required, and
// instantiation of Z<char>::g() required
}
Nothing in this example requires class Z<double>, Z<int>::g(), or Z<char>::f() to be implicitly
instantiated. — end example ]
Yes, it's possible in C++03 with CRTP (Curiously recurring template pattern):
#include <numeric>
#include <vector>
template<typename Derived, typename T>
struct Base
{
};
template<typename Derived>
struct Base<Derived, int>
{
int Sum() const
{
return std::accumulate(static_cast<Derived const*>(this)->myVector.begin(), static_cast<Derived const*>(this)->myVector.end(), int());
}
};
template<typename T>
class A : public Base<A<T>, T>
{
friend class Base<A<T>, T>;
protected:
std::vector<T> myVector;
public:
/*
constructors + a bunch of member functions here
*/
};
int main()
{
A<int> Foo;
Foo.Sum();
}
As an alternative solution, which works also in plain C++03 (as opposed to static_assert or enable_if solutions), you may add extra defaulted template argument which will let you have both
specialized and unspecialized version of class. Then you can inherit your specialized version from the unspecialized one.
Here is a sample snippet:
#include <vector>
template<typename T, bool unspecialized = false>
class A
{
protected:
std::vector<T> myVector;
public:
void setVec(const std::vector<T>& vec) { myVector = vec; }
/*
constructors + a bunch of member functions here
*/
};
template<>
class A<int, false> : public A<int, true>
{
public:
int onlyForInt() {
return 25;
}
};
int main() {
// your code goes here
std::vector<int> vec;
A<int> a;
a.setVec(vec);
a.onlyForInt();
return 0;
}
The drawbacks of this solution is the need to add constructor forwarders, if class
has non-trivial constructors.
The static_assert technique by #PiotrS. works nicely. But it's also nice to know that you can specialize a single member function without code duplication. Just give the generic onlyForInts() an empty no-op implementation, and specialize it out-of-class for int
#include <vector>
template <typename T>
class A
{
public:
void onlyForInts(T t)
{
// no-op
}
protected:
std::vector<T> myVector;
};
template<>
void A<int>::onlyForInts(int t)
{
// works
}
int main()
{
A<int> i;
i.onlyForInts(1); // works !
A<float> f;
f.onlyForInts(3.14f); // compiles, but does nothing !
}
Live Example.
This technique comes in handy if you want to have int specific behavior without completely disabling the generic behavior.
One approach not given yet in the answers is using the standard library std::enable_if to perform SFINAE on a base class that you inherit to the main class that defines appropriate member functions.
Example code:
template<typename T, class Enable = void>
class A_base;
template<typename T>
class A_base<T, typename std::enable_if<std::is_integral<T>::value>::type>{
public:
void only_for_ints(){/* integer-based function */}
};
template<typename T>
class A_base<T, typename std::enable_if<!std::is_integral<T>::value>::type>{
public:
// maybe specialize for non-int
};
template<typename T>
class A: public A_base<T>{
protected:
std::vector<T> my_vector;
};
This approach would be better than an empty function because you are being more strict about your API and better than a static_cast because it simply won't make it to the inside of the function (it won't exist) and will give you a nice error message at compile time (GCC shows "has no member named ‘only_for_ints’" on my machine).
The downside to this method would be compile time and code bloat, but I don't think it's too hefty.
(don't you dare say that C++11 requirement is a down-side, we're in 2014 god-damnit and the next standard has even be finalized already!)
Also, I noticed, you will probably have to define my_vector in the base class instead of the final because you probably want to handle that data within the member function.
A nice way to do that without duplicating a bunch of code is to create a base base class (good god) and inherit that class in the base class.
Example:
template<typename T>
class base_data{
protected:
std::vector<T> my_vector;
};
template<typename T>
class A_base<T, typename std::enable_if<std::is_integral<T>::value>::type>: public base_bata<T>{
public:
void only_for_ints(){/* phew, finally. fiddle around with my_vector! */}
};
// non-integer A-base
template<typename T>
class A: public A_base<T>{
protected:
// helper functions not available in base
};
That does leave a horrible looking multiple-inheritance scheme, but it is very workable and makes it easy to define members based on template parameters (for future proofing).
People often don't like multiple-inheritance or how complicated/messy SFINAE looks, but I couldn't live without it now that I know of it: the speed of static code with the polymorphism of dynamic code!
Not sure where I found this, but you can use = delete; as the function definition inside the class, thereby deleting the function for the general case, and then explicitly specialize outside the class:
template <typename T>
struct A
{
auto int_only(T) -> void = delete;
};
template <> auto A<int>::int_only(int) -> void {}
int main()
{
auto a_int = A<int>{};
auto a_dbl = A<double>{};
a_int.int_only(0);
// a_dbl.int_only(3.14); error: call to deleted member function
}
https://en.cppreference.com/w/cpp/language/function#Deleted_functions