Specializing Inherited template methods

Hello everibody,
I'm new here and I don't know if this topic has already been discussed, but I've been googling it and found nothing, so here I am.
So, I have this class that gives access to a variable into a physics model. Since I don't know in advance which datatype will be associated with the variable, I made template get/set methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
class ScalarVariable: public ModelVariable {
                protected:
                	ScalarVariable( ExecutingModel& modelInstance, Model&
                modelType, int nodeId );
                
                public:
                	virtual ~ScalarVariable();
                
                	template <class T>
                	const T getValue() const;
                	template <class T>
                	void setValue( const T v );
                };


Now I would like to have inherited classes that implement those template methods and specialize them if necessary, but I don't know how to write it with a proper synstax, e.g. if I write the following code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class IntegerVariable : public ScalarVariable {
                	friend class ModelVariableFactory;
                
                protected:
                	IntegerVariable(
                		ExecutingModel& modelInstance, 
                		Model& modelType, 
                		int nodeId);
                
                public:
                	virtual ~IntegerVariable();
                
                	const int getValue() const;
                	void setValue( const int v );
                };


I am told by Eclipse that the method const int getValue() const; "Shadows" the getValue from the parent class, so I assume it will never use the code from the parent class.

I would like to have a general ModelVariable class that is used i.e. to handle the result of a factory, just like
 
ModelVariable& v = ModelVariableFactory::createVariable( *modelInstance, *modelType, nodeId );


while the factory really would create an instance of IntegerVariable or BooleanVariable or RealVariable, etc...

Is this possible? Is this realistic?

Thank you for your collaboration!!!
xB;)

Try

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Parent
{
public:
	template <typename T>
	void Set(T aVal)
	{
		cout << "Set template" << endl;
	}
};

class Child : public Parent
{
public:
	void Set(int aVal)
	{
		cout << "Set int" << endl;
	}

	using Parent::Set;
};

int main()
{
	Child c;
	c.Set(5);
	c.Set(c);
	return 0;
}


Note that when you have a child class, it can override particular method, but having the name in the child's namespace will block other methods of the same name that are not overridden, unless you explicitly say to make the parent's methods available.
Can't you use boost::any or boost::variant<> ?

For example, with boost::any http://www.boost.org/doc/libs/1_49_0/doc/html/any.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <boost/any.hpp>
#include <string>
#include <iostream>

struct variable
{
    explicit variable( const boost::any& a /* model etc. */ ) : any(a) {}

    virtual ~variable() {}

    const boost::any& value() const { return any ; }
    void value( const boost::any& v ) { any = v ; }

    const std::type_info& type() const { return any.type() ; }
    template < typename T > const T& cast() const
    { return boost::any_cast< const T& >(any) ; }

    private: boost::any any ;
              // model etc.
};

template< typename T > struct scalar_variable : variable
{
    scalar_variable( const T& v /* model etc. */ ) : variable( v /* model etc. */ ) {}

    operator const T& () const { return cast<T>() ; }

    scalar_variable<T>& operator= ( const T& v ) { value(v) ; return *this ; }
};

template< typename T > scalar_variable<T> create_scalar_variable( const T& v /* model etc. */)
{ return scalar_variable<T>( v /* model etc. */ ) ; }


int main()
{
    std::vector<variable> vars = { create_scalar_variable(8),
                                   create_scalar_variable(34.7),
                                   create_scalar_variable( std::string("abcd") ),
                                   create_scalar_variable(5.3),
                                   create_scalar_variable(56) } ;
    for( variable& v : vars )
    {
        if( v.type() == typeid(int) )
            std::cout << "{ int: " << v.cast<int>() << " }, " ;
        else if( v.type() == typeid(double) )
            std::cout << "{ double: " << v.cast<double>() << " }, " ;
        else if( v.type() == typeid(std::string) )
            std::cout << "{ string: '" << v.cast<std::string>() << "' }, " ;
        else std::cout << "{ <unknown type> }, " ;
    }
    std::cout << '\n' ;

    scalar_variable<double>& d = static_cast< scalar_variable<double>& >( vars[3] ) ;
    std::cout << "d == " << d << '\n' ;
    d = -6.2 ;
    std::cout << "d == " << d << '\n' ;
}
Ok, thank you guys for your answers,
I found that rollie's solution doesn't work for me: I actually wanted to specify the template specialization without redefining it, I'll explain: I wanted to write
1
2
const int getValue() const;
using ScalarVariable::getValue;

because the code in ScalarVariable::getValue works very nice for me. So, what I did in, for instance, IntegerVariable is
1
2
3
const int getValue() {
	return ScalarVariable::getValue<int>();
}

which is actually what I wanted.
Borges, thank you for your tip, but I don't want to include Boost in my project, I have to keep it as light as possible.

Byez!
xB;)
Topic archived. No new replies allowed.