explicit specialization is not allowed in the current scope
When I tried to compile the following code, I am getting the following error. Please let me know how to go ahead with this....
Error: explicit specialization is not allowed in the current scope
template<>
bool insertTerm<std::string>(dm_Types::OperType oper,
const std::string& value) throw();
[340 byte] By [
Sara_Kan] at [2007-11-26 8:48:25]

# 1
When you create an explicit specialization of a template, the specialization must be declared and defined in the same scope as the primary template. Example: [code]
namespace N {
// primary template in namespace N
template<class T> int foo(T t) { ... }
}
// WRONG: attempted specialization in global scope
template<> int foo<int>(int T) { ... }
// CORRECT: specialization in same namespace
namespace N {
template<> int foo<int>(int T) { ... }
} [/code]
# 2
Thank you for your quick response... I appreciate that...
Well... I am sorry for not giving more information on this.... We are in the process of C++ compiler upgrade from 5.3 to 5.8.... This code compiles without any error with C++ 5.3 compiler.
When I compile with C++ 5.8 compiler, I am getting the above mentioned error. Should I think about namespace as I thought it was already abstraced by a class definition.
In the mean time, let me try to apply namespace here...
Actually, I have an class called dm_Index
Lets write the code
class dm_Index{
//Inside this I have this definition.
template< >
bool insertTerm<std::string>(dm_Types::OperType oper,
const std::string& value) throw();
}[code][/code]
# 3
I think that in order to understand why you've got the error, you'll need to show where your primary template for [b]bool dm_Index::insertTerm()[/b] is. If it is in different class, then the error looks just. Consider this example:
[code]
$ cat a.cc
#include <string>
#include <iostream>
class A
{
public:
template<typename T>
bool insertTerm() { return true; }
};
class B
{
public:
template<>
bool insertTerm<std::string>() { return false; } // line 15
};
int main()
{
A a;
B b;
std::cout << a.insertTerm<bool>() << b.insertTerm(); // line 22
return 1;
}
$ CC -g a.cc
"a.cc", line 15: Error: explicit specialization is not allowed in the current scope.
"a.cc", line 15: Error: Use ";" to terminate declarations.
"a.cc", line 22: Error: Only a function may be called.
3 Error(s) detected.
[/code]
CC generates exactly the same message.
# 4
The complete code is given below... I am not doing any inheritence... What I have been doing is overloaded functions. Two of then are compiling without errors and two of them are giving errors.
class dm_IndexPredicate
{
template <typename T> bool insertTerm(dm_Types::OperType oper, const T& value) throw();
/**
* Specialization for \c std::string.
**************************************************************************/
template< >
bool insertTerm<std::string>(dm_Types::OperType oper,const std::string& value) throw();
//Error as mentioned in the title
/**
* Insert the given operator into the predicate.
* This method will make sure that there is only this one term in the
* predicate.
*/
template <typename T> bool insertTerm(dm_Types::OperType oper) throw();
/**
* Specialization for \c std::string.
**************************************************************************/
template < > bool insertTerm<std::string>(dm_Types::OperType oper) throw();
//Error as mentioned in the title
};
# 5
Ah, yes, specialization within a class also leads to an error:
[code]class A
{
public:
template<typename T>
bool insertTerm() { return true; }
template <>
bool insertTerm<std::string>() { return false; }
};
[/code]
But this code compiles successfully:
[code]class A
{
public:
template<typename T>
bool insertTerm() { return true; }
};
template <>
bool A::insertTerm<std::string>() { return false; }[/code]
I think I'll leave explanation to Stephen.
# 6
Specialize your functions outside the class.
Code shows error:
[code]
struct S
{
template <typename T>
void foo(T) {}
template <>
void foo<int>(int) {}
};
int main()
{
S s;
s.foo(0);
s.foo(0.0);
return 0;
}
[/code]
Code without error:
[code]
struct S
{
template <typename T>
void foo(T) {}
};
template <>
void S::foo<int>(int) {}
int main()
{
S s;
s.foo(0);
s.foo(0.0);
return 0;
}
[/code]
# 7
For an explanation please look at C++ standard 14.7.3 clause 2:
"An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class template is a member. An explicit specialization of a member function, member class or static data member of a class template shall be declared in the namespace of which the class template is a member. Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later in the namespace in which the explicit specialization was declared, or in a namespace that encloses the one in which the explicit specialization was declared."
# 8
class dm_IndexPredicate
{
template <typename T> bool insertTerm(dm_Types::OperType oper, const T& value) throw();
/**
* Specialization for \c std::string.
**************************************************************************/
/**
* Insert the given operator into the predicate.
* This method will make sure that there is only this one term in the
* predicate.
*/
template <typename T> bool insertTerm(dm_Types::OperType oper) throw();
/**
* Specialization for \c std::string.
**************************************************************************/
};
template< >
bool insertTerm<std::string>(dm_Types::OperType oper,const std::string& value) throw();
template < > bool insertTerm<std::string>(dm_Types::OperType oper) throw();
When I move the explicit declaration outside the class it resolves the compiler error. However that is not the best solution becuase in the later stage of the code
template <> class IndexTerm<std::string> : public dm_IndexPredicate
is giving compilation error...
# 9
Your specialization of [b]insertTerm<std::string>[/b] is wrong: it is declared as global function, not class method. Specialization of a method should look like
[code]template< >
bool dm_IndexPredicate::insertTerm<std::string>(dm_Types::OperType oper,const std::string& value) throw();[/code]
# 10
template <> class IndexTerm<std::string> : public dm_IndexPredicate
The template member function...
template< >
bool insertTerm<std::string>(dm_Types::OperType oper,const std::string& value) throw();
In the class mentioned above has std::string specialization. After it is inherited from dm_IndexPredicate, it is not able to see the member function defined outside the class... It requires explicit namespaces to have them visible to the derived classes..... It is much more complex than what I had thought in my mind....
Byt the way MaximKartashev , the code that pasted here was not the one I compiled.... by the way I can differentiate the error between original compiler generated and my coding error... it is very clear in this compiler....
Thank you all for your information and I am going ahead with my implementation....