I have a template class in a header that fails to compile, but when I try to make a minimal show case, it compiles fine. I'm trying to make a class that can be constructed from an array, deducing the length automatically. The error is "reference to a zero-sized array is illegal", which makes no sense, as it should automatically deduce the length via the template.
Related Code:
template<class _Elem, bool _Null=true, bool _Trunc=false, class _Traits = std::char_traits<char>>
class basic_estring {
public:
typedef typename _Traits::pos_type size_type;
typedef typename _Elem value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
static const size_type npos;
basic_estring(const_pointer ptr, size_type capacity=npos, size_type used=npos);
template<int capacity> basic_estring(value_type (&data)[capacity], size_type used=npos);
// several hundred lines of other declarations
};
template<class _Elem, bool _Null, bool _Trunc, class _Traits>
basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(
typename basic_estring<_Elem,_Null,_Trunc,_Traits>::const_pointer ptr,
typename basic_estring<_Elem,_Null,_Trunc,_Traits>::size_type capacity,
typename basic_estring<_Elem,_Null,_Trunc,_Traits>::size_type used)
{} //This constructor has no problems (and all the others too)
template<class _Elem, bool _Null, bool _Trunc, class _Traits> template<int capacity>
basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(
typename basic_estring<_Elem,_Null,_Trunc,_Traits>::value_type (&data)[capacity], //LINE 218
typename basic_estring<_Elem,_Null,_Trunc,_Traits>::size_type used)
{} //LINE 228
//several hundred lines of definitions
And the error from MSVC C++ 2010:
1>/*snip*/\estring.h(218): error C2265: 'abstract declarator' : reference to a zero-sized array is illegal
1>/*snip*/\estring.h(228): error C2244: 'basic_estring<_Elem,_Null,_Trunc,_Traits>::{ctor}' : unable to match function definition to an existing declaration
1> definition
1> 'basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring<_Elem,_Null,_Trunc,_Traits>::value_type (&)[1],basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring<_Elem,_Null,_Trunc,_Traits>::size_type)'
1> existing declarations
1> 'basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(const basic_estring<_Elem,_Null,_Trunc,_Traits> &&)'
1> 'basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(const basic_estring<_Elem,_Null,_Trunc,_Traits> &)'
1> 'basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(const std::basic_string<_Elem,_Traits,Alloc> &)'
1> 'basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(_Elem (&)[capacity],_Traits::pos_type)'
1> 'basic_estring<_Elem,_Null,_Trunc,_Traits>::basic_estring(const _Elem *,_Traits::pos_type,_Traits::pos_type)'
Anyone know what I'm doing wrong? I'm usually pretty good about solving my own problems, but this has me stumped. I rewrote it from the other constructors, and that solved nothing.
[Edit] The error is still there when the non-prototype code in this project is
int main() {
return 0;
}
(including no function definitions) So, it isn't an instantiation problem as far as I can tell. While I was commenting out this code, I kept commenting out code from inside the class too, and discovered that if I commented out the member function prototype capacity
, the error goes away. My class does not inherit from any other classes.
void resize( size_type Count );
void resize( size_type Count, value_type Ch );
size_type capacity( ) const; //if this is commented, the error goes away.
void reserve( size_type Count );
Now I'm totally stumped. [/Edit]