How do i pull off something that would make the last commented line compile? How would i have to change this code to make it work?
#include<iostream>
using namespace std;
template <int x>
class someclass{
public:
int size;
int intarr[x];
someclass():size(x){}
};
template<int x, int y>
int somefunc(someclass<x> A, someclass<y> B){
return ( A.size > B.size ? A.size : B.size);
}
template<int x, int y, int z>
someclass<x> anotherfunc(someclass<y> A, someclass<z> B){
return ( A.size > B.size ? A : B);
}
int main(){
someclass<5> A;
someclass<10> B;
cout << "SIZE = " << somefunc(A,B) << endl;
//cout << "SIZE = " << (anotherfunc(A,B)).size << endl; //THIS DOES NOT COMPILE
return 0;
}
How is it supposed to know what
xis from outside the function? (It can’t look into the body, because in which body of which function it looks depends on what valuexgets!). Also you cannot write that?:because both your branches yield totally unrelated types that can’t possibly get to a common type. But that operator requires to have a common type for both branches that it evaluates to.And then the other problem you have that
sizeis not a compile time constant is already elaborated by another post.I think this should work:
Now when calling it,
yandzare deduced by the parameters, and then the parameters are substituted into the return type. Thesizeof(char[1 or 0])will test whetheryorzis greater. In the respective template that evaluates this tosizeof(char[1])(which yields 1) we will multiply by the value that is greater (or equal). If the respective template yieldssizeof(char[0])this is a deduction failure (an array can’t be of zero size!) and the template won’t get selected by overload resolution (known as SFINAE).The unary
+yields1or0as int instead oftrueorfalse, which could cause compiler warnings for some compilers.There is also the “clean” way with
enable_if. It’s not doing hideoussizeoftricks, but rather using the general established enable_if pattern. Boost has an implementation of itThis may at first sight look more noisy, but should be easier to understand and faster to follow to folks that are already used to
enable_if(the_cvariant of boost’s implementation accepts plain booleans, as above).