S
Siemel Naran
Here is a question about implicit conversion from T (&)[N] to ptrcarray<T>.
I wrote a class
template <class T>
struct ptrcarray
{
T * array;
size_t size;
ptrcarray() : array(NULL), size(0) { }
template <size_t N> ptrcarray(T (&array)[N]) : array(array), size(N) { }
};
Given a function
void f(const ptrcarray<int>& p);
then I expect the following code to compile
int a[] = { 1, 2, 3 };
f(a);
I expect the call to f(a) to convert 'a' of type int(&)[3] to a
ptrcarray<int> because of the implicit constructor ptrcarray<T>:
trcarray(T
(&)[N]) with T as int and N as 3.
But both Borland and g++ give an error.
e.cc: In function `int realmain(int, const char *const *, const char *const
*)':
Borland 6.0 error ==>
e.cc:33: conversion from `int *' to non-scalar type `ptrcarray<int>'
requested
e.cc:20: in passing argument 1 of `f(const ptrcarray<int> &)'
g++ 2.95.2-6 error ==>
e.cc:33: conversion from `int *' to non-scalar type `ptrcarray<int>'
requested
e.cc:20: in passing argument 1 of `f(const ptrcarray<int> &)'
But if I specify the type explicitly, then it compiles and runs fine on g++
(but on Borland I get an internal compiler error).
int a[] = { 1, 2, 3 };
f(ptrcarray<int>(a));
The question: Are my compilers broken or is my code broken (probably the
latter, but I need to check)?
The full program follows for anyone interested:
//////////////////////////////////////////////////
// realmain.cpp
#include <string>
#include <iostream>
using std::cout;
template <class T>
struct ptrcarray
{
T * array;
size_t size;
ptrcarray() : array(NULL), size(0) { }
template <size_t N> ptrcarray(T (&array)[N]) : array(array), size(N) { }
};
void f(const ptrcarray<int>& p)
{
cout << static_cast<void*>(p.array) << '\t' << p.size << '\n';
}
void g(const ptrcarray<const int>& p)
{
cout << static_cast<const void*>(p.array) << '\t' << p.size << '\n';
}
int realmain(int argc, char const *const * argv, char const *const * env)
{
int a[] = { 1, 2, 3 };
const int b[] = { 1, 2, 3 };
//f(a);
//g(b);
f(ptrcarray<int>(a));
g(ptrcarray<const int>(b));
return 0;
}
//////////////////////////////////////////////////
// main.cpp
#include <exception>
int main(int argc, char * * argv, char * * env)
{
using std::cerr;
try
{
return realmain(
argc,
const_cast<const char *const *>(argv),
const_cast<const char *const *>(env)
);
}
catch (const std::exception& e)
{
cerr << "exception: " << e.what() << "\n";
}
catch (...)
{
cerr << "unhandled exception\n";
}
return 1;
}
I wrote a class
template <class T>
struct ptrcarray
{
T * array;
size_t size;
ptrcarray() : array(NULL), size(0) { }
template <size_t N> ptrcarray(T (&array)[N]) : array(array), size(N) { }
};
Given a function
void f(const ptrcarray<int>& p);
then I expect the following code to compile
int a[] = { 1, 2, 3 };
f(a);
I expect the call to f(a) to convert 'a' of type int(&)[3] to a
ptrcarray<int> because of the implicit constructor ptrcarray<T>:
(&)[N]) with T as int and N as 3.
But both Borland and g++ give an error.
e.cc: In function `int realmain(int, const char *const *, const char *const
*)':
Borland 6.0 error ==>
e.cc:33: conversion from `int *' to non-scalar type `ptrcarray<int>'
requested
e.cc:20: in passing argument 1 of `f(const ptrcarray<int> &)'
g++ 2.95.2-6 error ==>
e.cc:33: conversion from `int *' to non-scalar type `ptrcarray<int>'
requested
e.cc:20: in passing argument 1 of `f(const ptrcarray<int> &)'
But if I specify the type explicitly, then it compiles and runs fine on g++
(but on Borland I get an internal compiler error).
int a[] = { 1, 2, 3 };
f(ptrcarray<int>(a));
The question: Are my compilers broken or is my code broken (probably the
latter, but I need to check)?
The full program follows for anyone interested:
//////////////////////////////////////////////////
// realmain.cpp
#include <string>
#include <iostream>
using std::cout;
template <class T>
struct ptrcarray
{
T * array;
size_t size;
ptrcarray() : array(NULL), size(0) { }
template <size_t N> ptrcarray(T (&array)[N]) : array(array), size(N) { }
};
void f(const ptrcarray<int>& p)
{
cout << static_cast<void*>(p.array) << '\t' << p.size << '\n';
}
void g(const ptrcarray<const int>& p)
{
cout << static_cast<const void*>(p.array) << '\t' << p.size << '\n';
}
int realmain(int argc, char const *const * argv, char const *const * env)
{
int a[] = { 1, 2, 3 };
const int b[] = { 1, 2, 3 };
//f(a);
//g(b);
f(ptrcarray<int>(a));
g(ptrcarray<const int>(b));
return 0;
}
//////////////////////////////////////////////////
// main.cpp
#include <exception>
int main(int argc, char * * argv, char * * env)
{
using std::cerr;
try
{
return realmain(
argc,
const_cast<const char *const *>(argv),
const_cast<const char *const *>(env)
);
}
catch (const std::exception& e)
{
cerr << "exception: " << e.what() << "\n";
}
catch (...)
{
cerr << "unhandled exception\n";
}
return 1;
}