443,784 Members | 3,536 Online Need help? Post your question and get tips & solutions from a community of 443,784 IT Pros & Developers. It's quick & easy.

# Make t2 const: T1 (&aPlus(T1(&t1)[S],T2(&t2)[S]))[S]

 P: n/a In the following code, the only way I can figure out to pass an array of const is by setting the template argument to const in the instanciation expression. It would be (or seem to me) better if I could set that qualifier in the function call. Can that be done? #include using std::ostream; using std::cout; template void printArray(T array[], ostream& out=cout) { out << "{"; for(unsigned i = 0;i < ORDER; i++ ){ out << array[i]; if(i < ORDER - 1){ out << ",";} } out << "}\n\n"; } template T1 (&aPlus(T1(&t1)[ORDER], T2(&t2)[ORDER]))[ORDER] { for(unsigned i = 0;i < ORDER; i++ ) { t1[i] += t2[i]; } return t1; } template void test_aPlus() { T a0[ORDER]; T a1[ORDER]; for(unsigned i = 0; i < ORDER; i++) { a0[i]=i; a1[i]=i*i; } aPlus(a0,a1); printArray(a0); printArray(a1); T(&ar)[ORDER]=a1; aPlus(a0,ar); printArray(a0); printArray(ar); const T(&car)[ORDER]=a1; /** uncomment the following line and it won't compile **************************/ //aPlus(a0,car); aPlus(a0,car); printArray(a0); printArray(car); } int main() { test_aPlus<5,float>(); return 0; } -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #1
16 Replies

 P: n/a Steven T. Hatton wrote: In the following code, the only way I can figure out to pass an array of const is by setting the template argument to const in the instanciation expression. It would be (or seem to me) better if I could set that qualifier in the function call. Can that be done? I'm not sure exactly what you're trying to do, however you can overload aPlus. Jul 22 '05 #2

 P: n/a Gianni Mariani wrote: Steven T. Hatton wrote: In the following code, the only way I can figure out to pass an array of const is by setting the template argument to const in the instanciation expression. It would be (or seem to me) better if I could set that qualifier in the function call. Can that be done? I'm not sure exactly what you're trying to do, however you can overload aPlus. Did you compile and run the code? With, and without the commented line /** *****uncomment*the*following*line*and*it*won't*com pile ****************************/ **//aPlus(a0,car); ? I'm trying to make the second parameter const in this function template: template T1 (&aPlus(T1(&t1)[ORDER],**T2(&t2)[ORDER]))[ORDER]; Do you know how to do that? -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #3

 P: n/a Steven T. Hatton wrote: Gianni Mariani wrote:Steven T. Hatton wrote:In the following code, the only way I can figure out to pass an array ofconst is by setting the template argument to const in the instanciationexpression. It would be (or seem to me) better if I could set thatqualifier in the function call. Can that be done?I'm not sure exactly what you're trying to do, however you can overloadaPlus. Did you compile and run the code? With, and without the commented line /** uncomment the following line and it won't compile **************************/ //aPlus(a0,car); ? I'm trying to make the second parameter const in this function template: template T1 (&aPlus(T1(&t1)[ORDER], T2(&t2)[ORDER]))[ORDER]; Do you know how to do that? Yes. Try the code below - note the overloaded aPlus. Also, you don't need to specify the template parameters, they can be deduced by the compiler. i.e. aPlus(a0,car); // this won't work with the overloading below // but will work with the OP code. That's what I am confused about, why are you specifying the template parameters when they can be deduced ? #include using std::ostream; using std::cout; template void printArray(T array[], ostream& out=cout) { out << "{"; for(unsigned i = 0;i < ORDER; i++ ){ out << array[i]; if(i < ORDER - 1){ out << ",";} } out << "}\n\n"; } template T1 (&aPlus(T1(&t1)[ORDER], T2(&t2)[ORDER]))[ORDER] { for(unsigned i = 0;i < ORDER; i++ ) { t1[i] += t2[i]; } return t1; } template T1 (&aPlus(T1(&t1)[ORDER], const T2(&t2)[ORDER]))[ORDER] { for(unsigned i = 0;i < ORDER; i++ ) { t1[i] += t2[i]; } return t1; } template void test_aPlus() { T a0[ORDER]; T a1[ORDER]; for(unsigned i = 0; i < ORDER; i++) { a0[i]=i; a1[i]=i*i; } aPlus(a0,a1); printArray(a0); printArray(a1); T(&ar)[ORDER]=a1; aPlus(a0,ar); printArray(a0); printArray(ar); const T(&car)[ORDER]=a1; /** uncomment the following line and it won't compile **************************/ aPlus(a0,car); // aPlus(a0,car); printArray(a0); printArray(car); } int main() { test_aPlus<5,float>(); return 0; } Jul 22 '05 #4

 P: n/a Steven T. Hatton wrote: Gianni Mariani wrote: #include using std::ostream; using std::cout; template void printArray(T array[], ostream& out=cout) { out << "{"; for(unsigned i = 0;i < ORDER; i++ ){ out << array[i]; if(i < ORDER - 1){ out << ",";} } out << "}\n\n"; } template T1 (&aPlus(T1(&t1)[ORDER], T2(&t2)[ORDER]))[ORDER] { for(unsigned i = 0;i < ORDER; i++ ) { t1[i] += t2[i]; } return t1; } template T1 (&aPlus(T1(&t1)[ORDER], const T2(&t2)[ORDER]))[ORDER] { for(unsigned i = 0;i < ORDER; i++ ) { t1[i] += t2[i]; } return t1; } OK. I see what you're saying. I guess I was confused by the fact that very similar code using normal array notation without the references didn't require any overloading. I guess I've never hit the overloading issue from this direction before. I'm still confused about what this means. My understanding of making a parameter const is that the function won't modify it. That's what I want. Normally, I can pass a non-const variable as a const reference. void cfun( const string& cstr) { cout << cstr; } int main() { string str = "This is a non-const variable\"; cfun(str); } So why should I have to overload that function? -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #6

 P: n/a Steven T. Hatton wrote: I'm still confused about what this means. My understanding of making a parameter const is that the function won't modify it. That's what I want. Normally, I can pass a non-const variable as a const reference. void cfun( const string& cstr) { cout << cstr; } int main() { string str = "This is a non-const variable\"; cfun(str); } So why should I have to overload that function? In the OP (original post) example, it shows a const object being assigned to a non const reference, this is not allowed. C++ can deduce template parameters in function templates AND you can overload functions which becomes a rather rich area of the language with all kinds of rope to hang ourselves. e.g. template < typename T1, typename T2 > void f1( const T1 &, const T2 & ); template < typename T1, typename T2 > void f2( T1 &, T2 & ); struct X; struct Y; const X & x; Y & y; f1( x, y ); // ==> T1 is X, T2 is Y f2( x, y ); // ==> T1 is const X, T2 is Y Jul 22 '05 #7

 P: n/a "Steven T. Hatton" wrote: Steven T. Hatton wrote: template T1 (&aPlus(T1(&t1)[ORDER], const T2(&t2)[ORDER]))[ORDER] { } I'm still confused about what this means. My understanding of making a parameter const is that the function won't modify it. That's what I want. I think what you want is for the referred-to things to be const, not the parameter being const. In fact it is not permitted to make a reference const (because they cannot be reassigned anyway). Normally, I can pass a non-const variable as a const reference. void cfun( const string& cstr) That is a reference to const string (not a const reference to string). If you still don't see the difference then consider: void foo(int *const ptr) { *ptr = 2; } vs. void foo(int const *ptr) { int const y = 2; ptr = &y; } In the first one, the parameter is const but the pointed-to things are not; in the second one, it is the other way around. In your case it is even worse as 'const' could be applied either to the entire array, or to its members. int main() { string str = "This is a non-const variable\"; cfun(str); } So why should I have to overload that function? The type 'array of const T2' is not the same as 'const (array of T2)'. Jul 22 '05 #8

 P: n/a Gianni Mariani wrote: Steven T. Hatton wrote: I'm still confused about what this means. My understanding of making a parameter const is that the function won't modify it. That's what I want. Normally, I can pass a non-const variable as a const reference. void cfun( const string& cstr) { cout << cstr; } int main() { string str = "This is a non-const variable\"; cfun(str); } So why should I have to overload that function? In the OP (original post) example, it shows a const object being assigned to a non const reference, this is not allowed. template T1 (&aPlus(T1(&t1)[ORDER], const T2(&t2)[ORDER]))[ORDER] { for(unsigned i = 0;i < ORDER; i++ ) { t1[i] += t2[i]; } return t1; } aPlus(a0,car); // this works aPlus(a0,car); // this works aPlus(a0,car); // this doesn't Why isn't car treated as const in the last statement? C++ can deduce template parameters in function templates AND you can overload functions which becomes a rather rich area of the language with all kinds of rope to hang ourselves. e.g. template < typename T1, typename T2 > void f1( const T1 &, const T2 & ); template < typename T1, typename T2 > void f2( T1 &, T2 & ); struct X; struct Y; const X & x; Y & y; f1( x, y ); // ==> T1 is X, T2 is Y f2( x, y ); // ==> T1 is const X, T2 is Y I'm not following this code. Is it what you had intended to write? -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #9

 P: n/a Old Wolf wrote: I think what you want is for the referred-to things to be const, not the parameter being const. In fact it is not permitted to make a reference const (because they cannot be reassigned anyway). Sorry, I should have worded that better. I do understand that distinction. So why should I have to overload that function? The type 'array of const T2' is not the same as 'const (array of T2)'. The following says aPlus is a function that returns a reference to an array of type T2: T1 (&aPlus(T1(&t1)[S],T2(&t2)[S]))[S]; Does this say aPlus is a function that returns a reference to an array of type const T2: T1 (&aPlus(T1(&t1)[S],const T2(&t2)[S]))[S]; ? -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #10

 P: n/a Steven T. Hatton wrote: Old Wolf wrote:I think what you want is for the referred-to things to be const,not the parameter being const. In fact it is not permittedto make a reference const (because they cannot be reassigned anyway). Sorry, I should have worded that better. I do understand that distinction.So why should I have to overload that function?The type 'array of const T2' is not the same as 'const (array of T2)'. The following says aPlus is a function that returns a reference to an array of type T2: T1 (&aPlus(T1(&t1)[S],T2(&t2)[S]))[S]; when reading C++ (and C) types you need to start from the identifier. aPlus is a function that takes parameters t1 and t2 returning a reference to an array of length S of T1. Does this say aPlus is a function that returns a reference to an array of type const T2: T1 (&aPlus(T1(&t1)[S],const T2(&t2)[S]))[S]; ? This is the same as the previous one except that t2 is a const T2. Jul 22 '05 #11

 P: n/a Steven T. Hatton wrote: Old Wolf wrote: I think what you want is for the referred-to things to be const, not the parameter being const. In fact it is not permitted to make a reference const (because they cannot be reassigned anyway). Sorry, I should have worded that better. I do understand that distinction. So why should I have to overload that function? The type 'array of const T2' is not the same as 'const (array of T2)'. The following says aPlus is a function that returns a reference to an array of type T2: T1 (&aPlus(T1(&t1)[S],T2(&t2)[S]))[S]; Does this say aPlus is a function that returns a reference to an array of type const T2: T1 (&aPlus(T1(&t1)[S],const T2(&t2)[S]))[S]; ? Sorry I meant to say "and takes arguments of reference to array of type T1 and reference to array of type (const) T2", not returns ... const ... -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #12

 P: n/a Gianni Mariani wrote: Steven T. Hatton wrote: type const T2: T1 (&aPlus(T1(&t1)[S],const T2(&t2)[S]))[S]; ? This is the same as the previous one except that t2 is a const T2. That's what I expected. T a0 = {10,20,30}; T a1 = {1,2,3}; T(&ar)=a1; const T(&car)=a1; aPlus(a0,car);//works aPlus(a0,car); //works aPlus(a0,car); // won't compile I would expect the last call to be treated as: aPlus(T(&a0), const T(&a1))); I think my confusion is that I don't really understand what the template parameters are doing. -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #13

 P: n/a Steven T. Hatton wrote: .... That's what I expected. T a0 = {10,20,30}; T a1 = {1,2,3}; T(&ar)=a1; const T(&car)=a1; aPlus(a0,car);//works aPlus(a0,car); //works aPlus(a0,car); // won't compile I would expect the last call to be treated as: aPlus(T(&a0), const T(&a1))); I think my confusion is that I don't really understand what the template parameters are doing. Assuming that this is your funtion aPlus. template T1 (&aPlus(T1(&t1)[ORDER], T2(&t2)[ORDER]))[ORDER] What you're doing is when you instantiate aPlus is creating a function like: T (&aPlus(T(&t1)[ORDER], T(&t2)[ORDER]))[ORDER]; Then you try to pass "car", which is a const T array to a non const T array reference. The compiler shoul not compile that. Jul 22 '05 #14 