Problem with templates

I am getting this error and warning:


error: invalid declarator before '(' character
warning: deprecated conversion from string constant to char*


with this piece of code:

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

template <typename varType>
class Variable
{
private:
    varType value;
public:
    Variable(varType arg_value) : value(arg_value) {}
    Variable<char*>(char* arg_string) // ERROR HERE
    {
        value = new char[strlen(arg_string)];
        strcpy(value, arg_string);
    }

    varType GetValue();
};

template <typename varType>
varType Variable<varType>::GetValue()
{
    return value;
}

int main()
{
    Variable<int> integer(5);
    cout << integer.GetValue() << "\n";

    Variable<char*> stringVar("Hey"); // WARNING HERE
    cout << stringVar.GetValue() << "\n";

    return 0;
}


What is the solution to this problem?
Variable<char*>(char* arg_string)


You may not specify a class specialization for the constructor name while declares it. Either you shall specialize the whole class or define a template constructor and specialize it.
Could you give me an example of each, please?
Last edited on
For example if to use explicit specialization of the class

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
#include <iostream>
#include <cstring>

using namespace std;

template <typename varType>
class Variable
{
private:
    varType value;
public:
    Variable( varType arg_value) : value( arg_value) {}
    varType GetValue() const;
};

template <typename varType>
varType Variable<varType>::GetValue() const
{
    return value;
}

template <>
class Variable<char *>
{
private:
    char *value;
public:
    Variable( const char* arg_string)    {
        value = new char[strlen(arg_string) + 1];
        strcpy(value, arg_string);
    }

    char * GetValue() const;
};

char * Variable<char *>::GetValue() const
{
    return value;
}

int main()
{
    Variable<int> integer(5);
    cout << integer.GetValue() << "\n";

    Variable<char*> stringVar("Hey"); // WARNING HERE
    cout << stringVar.GetValue() << "\n";

    return 0;
}
what about
1
2
3
4
5
template<>
Variable<char*>::Variable( const char* arg_string){
   value = new char[strlen(arg_string) + 1];
   strcpy(value, arg_string);
}
@ne555
I think your code shall ot be compiled because char * and const char * are different types.

@Flurite


To make only specialization of the constructor the code can be written the following way

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
#include <iostream>
#include <cstring>

using namespace std;

 
template <typename varType>
class Variable
{
private:
    varType value;
public:
    Variable( const varType &arg_value) : value( arg_value) {}
    varType GetValue() const;
};

template <typename varType>
varType Variable<varType>::GetValue() const
{
    return value;
}

template <>
Variable<char *>::Variable( char * const  &arg_string)    {
        value = new char[strlen(arg_string) + 1];
        strcpy(value, arg_string);
    }

int main()
{
    Variable<int> integer(5);
    cout << integer.GetValue() << "\n";

    Variable<char*> stringVar("Hey"); // WARNING HERE
    cout << stringVar.GetValue() << "\n";

    return 0;
}
Thanks for the help guys!

A questions about your code though..

1. I realized that you are using an empty template declaration. I also figured out that you need an empty template declaration every time you must declare and define another constructor, and a template declaration with proper parameter when you are trying to define a function.

Do x template declarations tell the compiler that there will be x definitions of functions/constructors for templates (could be different templates)?
Last edited on
Any ideas? Or does the empty template declaration simply tell the compiler a specialized template definition is coming directly after the empty template declaration?
closed account (zb0S216C)
template<> is necessary, because you're telling the compiler you know what the type is, and to expect it.

Wazzak
Last edited on
Must you define the specialization directly after the template<>?
closed account (zb0S216C)
Yes. The the lexer/parser will expect a specialisation after template<>.

You can define a specialisation anywhere after the base-class definition, such as source files, headers, in-line files, etcetera. Specialised templates are permitted to be within source files, because specialised templates are complete types, and therefore, the compiler has all the information it needs to compile the template.

Wazzak
Topic archived. No new replies allowed.