Thread: Templates and Macros plus more...

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    There doesn't seem to be any reason for the compiler to copy the object as it is only being used in the caller function.
    There doesn't seem to be any reason for the compiler to not copy the object, since that's what it's supposed to do.
    5. A stack is implemented as, well, a stack. You can pass storage for the return value in by reference, or use dynamic memory. Compilers may try to optimize this, but if your classes get just a little complicated, they'll get lost. Yeah, compilers are dumb. Deal with it.
    4. "When typeid is applied to classes typeid uses the run-time type information to keep track of the type of dynamic objects." - CPlusPlus.com
    3. Boost is open source.
    2. The compiler will do it anyway, if you try to use + and /, like std::accumulate and your function do.
    1. C++ is not for you. Try Lisp instead.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  2. #2
    Registered User
    Join Date
    Aug 2006
    Posts
    14
    Thanks for the answers. I wasn't sure if a lot of the stuff I wanted was even possible.

    1. Lisp is great. Its unfortunate that c macros aren't as good apparently

    2. The main reason I wanted this to happen is so that the error occurs in the caller code, not my code. Then, if a template function is used inside another template functions, it becomes very difficult to track the original cause of the error as the error message generated is huge. For example
    Code:
    #include <iostream>
    #include <vector>
    #include <numeric>
    #include <string>
    
    using std::vector;
    using std::ostream;
    /* very simple class */
    class Lame {
    
        friend ostream& operator <<(ostream &os, const Lame &obj)
        {
            return os << "Lame object\n";
        }
    public:
        //Lame operator+(Lame& a) {
        //    return Lame();
        //} uncommenting this makes the code work
        
    
    };
    /* sums all the elements in the vector. Only needs + defined
    eg it will work with a string */
    template <typename T>
    T sumAll(vector<T> v)
    {
        return std::accumulate(v.begin(), v.end(), T());
    }
    
    /* Sums all the elements but each element is summed
    multiple times
    */
    template <typename T>
    T sumAllRepeat(vector<T> numbers, unsigned int times)
    {
        vector<T> allN;
        for(unsigned int i = 0; i < numbers.size(); i++) {
            for(unsigned int j = 0; j < times; j++) {
                allN.push_back(numbers[i]);
            }
        }
        return sumAll(allN);
    }
    
    
    int main() {
    
    
        vector<std::string> v1;
        v1.push_back("a");
        v1.push_back("b");
        std::cout << sumAllRepeat(v1, 4); // this works (aaaabbbb)
    
    
        vector<Lame> v2;
        v2.push_back(Lame());
        v2.push_back(Lame());
        std::cout <<  sumAll(v2); // this creates an error
        
    
        std::cin.get();
    	return 0;
    }
    The code compiles and works correctly without the red line, but with it it generates the compile error message:


    PHP Code:
    Compiling...
    OneFileTest.cpp
    d
    :\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(61) : see declaration of 'std::operator +'
            
    d:\program files\microsoft visual studio 8\vc\include\numeric(31) : see reference to function template instantiation '_Ty std::_Accumulate<std::_Vector_iterator<_Ty,_Alloc>,_Ty>(_InIt,_InIt,_Ty)' being compiled
            with
            
    [
                
    _Ty=Lame,
                
    _Alloc=std::allocator<Lame>,
                
    _InIt=std::_Vector_iterator<Lame,std::allocator<Lame>>
            ]
            
    c:\programming\cpp\onefiletest.cpp(27) : see reference to function template instantiation '_Ty std::accumulate<std::_Vector_iterator<_Ty,_Alloc>,Lame>(_InIt,_InIt,_Ty)' being compiled
            with
            
    [
                
    _Ty=Lame,
                
    _Alloc=std::allocator<Lame>,
                
    _InIt=std::_Vector_iterator<Lame,std::allocator<Lame>>
            ]
            
    c:\programming\cpp\onefiletest.cpp(58) : see reference to function template instantiation 'T sumAll<Lame>(std::vector<_Ty>)' being compiled
            with
            
    [
                
    T=Lame,
                
    _Ty=Lame
            
    ]
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(51) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const _Elem,const std::basic_string<_Elem,_Traits,_Alloc> &)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(41) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' could not deduce template argument for 'const _Elem *' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(31) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(21) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vb_iterator<_MycontTy> std::operator +(_Vb_iterator<_MycontTy>::difference_type,std::_Vb_iterator<_MycontTy>)' could not deduce template argument for 'std::_Vb_iterator<_MycontTy>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(1800) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vb_const_iterator<_MycontTy> std::operator +(_Vb_const_iterator<_MycontTy>::difference_type,std::_Vb_const_iterator<_MycontTy>)' could not deduce template argument for 'std::_Vb_const_iterator<_MycontTy>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(1695) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vector_iterator<_Ty,_Alloc> std::operator +(_Vector_iterator<_Ty,_Alloc>::difference_type,std::_Vector_iterator<_Ty,_Alloc>)' could not deduce template argument for 'std::_Vector_iterator<_Ty,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(396) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vector_const_iterator<_Ty,_Alloc> std::operator +(_Vector_const_iterator<_Ty,_Alloc>::difference_type,std::_Vector_const_iterator<_Ty,_Alloc>)' could not deduce template argument for 'std::_Vector_const_iterator<_Ty,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(264) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_String_iterator<_Elem,_Traits,_Alloc> std::operator +(_String_iterator<_Elem,_Traits,_Alloc>::difference_type,std::_String_iterator<_Elem,_Traits,_Alloc>)' could not deduce template argument for 'std::_String_iterator<_Elem,_Traits,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\xstring(438) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_String_const_iterator<_Elem,_Traits,_Alloc> std::operator +(_String_const_iterator<_Elem,_Traits,_Alloc>::difference_type,std::_String_const_iterator<_Elem,_Traits,_Alloc>)' could not deduce template argument for 'std::_String_const_iterator<_Elem,_Traits,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\xstring(298) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::reverse_iterator<_RanIt> std::operator +(_Diff,const std::reverse_iterator<_RanIt> &)' could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\xutility(1809) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2676binary '+' 'Lame' does not define this operator or a conversion to a type acceptable to the predefined operator 




    Note how hard it is to determine the cause of the compile error: the main method is not mentioned once in the error message but is the method that contained the bug.

    4.
    When typeid is applied to classes typeid uses the run-time type information to keep track of the type of dynamic objects
    Does this mean that for every object, a pointer for that object is kept to point to the rtti information? I understand that that already occurs for derived classes, but what about classes like vector and string, as well as primitive types? I'm just concerned that using typeid will force the compiler to use much more memory than it needs to.

    5. Oh well. I mainly needed it for efficiency but it doesn't really matter

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Monkeymagic
    The code compiles and works correctly without the red line, but with it it generates the compile error message:
    PHP Code:
    Compiling...
    OneFileTest.cpp
    d
    :\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(61) : see declaration of 'std::operator +'
            
    d:\program files\microsoft visual studio 8\vc\include\numeric(31) : see reference to function template instantiation '_Ty std::_Accumulate<std::_Vector_iterator<_Ty,_Alloc>,_Ty>(_InIt,_InIt,_Ty)' being compiled
            with
            
    [
                
    _Ty=Lame,
                
    _Alloc=std::allocator<Lame>,
                
    _InIt=std::_Vector_iterator<Lame,std::allocator<Lame>>
            ]
            
    c:\programming\cpp\onefiletest.cpp(27) : see reference to function template instantiation '_Ty std::accumulate<std::_Vector_iterator<_Ty,_Alloc>,Lame>(_InIt,_InIt,_Ty)' being compiled
            with
            
    [
                
    _Ty=Lame,
                
    _Alloc=std::allocator<Lame>,
                
    _InIt=std::_Vector_iterator<Lame,std::allocator<Lame>>
            ]
            
    c:\programming\cpp\onefiletest.cpp(58) : see reference to function template instantiation 'T sumAll<Lame>(std::vector<_Ty>)' being compiled
            with
            
    [
                
    T=Lame,
                
    _Ty=Lame
            
    ]
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(51) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const _Elem,const std::basic_string<_Elem,_Traits,_Alloc> &)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(41) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' could not deduce template argument for 'const _Elem *' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(31) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\string(21) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vb_iterator<_MycontTy> std::operator +(_Vb_iterator<_MycontTy>::difference_type,std::_Vb_iterator<_MycontTy>)' could not deduce template argument for 'std::_Vb_iterator<_MycontTy>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(1800) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vb_const_iterator<_MycontTy> std::operator +(_Vb_const_iterator<_MycontTy>::difference_type,std::_Vb_const_iterator<_MycontTy>)' could not deduce template argument for 'std::_Vb_const_iterator<_MycontTy>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(1695) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vector_iterator<_Ty,_Alloc> std::operator +(_Vector_iterator<_Ty,_Alloc>::difference_type,std::_Vector_iterator<_Ty,_Alloc>)' could not deduce template argument for 'std::_Vector_iterator<_Ty,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(396) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_Vector_const_iterator<_Ty,_Alloc> std::operator +(_Vector_const_iterator<_Ty,_Alloc>::difference_type,std::_Vector_const_iterator<_Ty,_Alloc>)' could not deduce template argument for 'std::_Vector_const_iterator<_Ty,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\vector(264) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_String_iterator<_Elem,_Traits,_Alloc> std::operator +(_String_iterator<_Elem,_Traits,_Alloc>::difference_type,std::_String_iterator<_Elem,_Traits,_Alloc>)' could not deduce template argument for 'std::_String_iterator<_Elem,_Traits,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\xstring(438) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::_String_const_iterator<_Elem,_Traits,_Alloc> std::operator +(_String_const_iterator<_Elem,_Traits,_Alloc>::difference_type,std::_String_const_iterator<_Elem,_Traits,_Alloc>)' could not deduce template argument for 'std::_String_const_iterator<_Elem,_Traits,_Alloc>' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\xstring(298) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2784'std::reverse_iterator<_RanIt> std::operator +(_Diff,const std::reverse_iterator<_RanIt> &)' could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'Lame'
            
    d:\program files\microsoft visual studio 8\vc\include\xutility(1809) : see declaration of 'std::operator +'
    d:\program files\microsoft visual studio 8\vc\include\numeric(23) : error C2676binary '+' 'Lame' does not define this operator or a conversion to a type acceptable to the predefined operator 


    Note how hard it is to determine the cause of the compile error: the main method is not mentioned once in the error message but is the method that contained the bug.
    You just need to learn to read the error messages. Granted, it's not as easy as it could be. But the first few lines make it obvious the cause is related to class Lame, and the last line actually describes the real cause of the error.

    In any event, you might want to do some digging on traits classes. Traits classes are used (in the STL and, incidentally by boost) to enforce conditions that are required for a class to be used with particular conditions. For example, supporting particular conversions. It would probably be possible to use such a technique to enforce a requirement that an expression "a+b" is valid for your type.

    Quote Originally Posted by Monkeymagic
    Does this mean that for every object, a pointer for that object is kept to point to the rtti information? I understand that that already occurs for derived classes, but what about classes like vector and string, as well as primitive types? I'm just concerned that using typeid will force the compiler to use much more memory than it needs to.
    I wouldn't worry about it.

    It depends on the compiler and how it implements classes and, naturally, the typeid operator i.e. it's an issue related to quality of implementation of your compiler. Most classes will need to be associated with some information about their type, to support operators like typeid() and dynamic_cast<>. That overhead will normally be there regardless of whether you use those operators, as the compiler can't judge if some other function (eg in another source) will use those operators. So, it is probably something that compiler vendors will optimise very carefully to minimise memory or performance overhead.

    Quote Originally Posted by Monkeymagic
    5. Oh well. I mainly needed it for efficiency but it doesn't really matter
    It is possible to avoid temporaries by careful design. For example, using a += b will avoid a temporary that a = a+b; would introduce by default (and that the compiler would have trouble eliminating for user-defined types, as there is not necessarily a 1-1 correspondence between the += operator and + operator).

    You might want to look ip the blitz++ numeric library. It is a C++ template library designed around numerics. It also uses some pretty clever techniques to avoid temporaries (as some of the objects they pass around, such as large matrices) are very costly to copy.

    The C++ standard explicitly makes some allowances so that the RVO (and some other optimisations of temporaries out of existance) are feasible. For example, a temporary does not need to be created if the ONLY way of detecting its existance is by tracking constructor and destructor calls. However, again we get in the domain of quality of implementation of compilers: it is up to the compiler vendor as to whether they do that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 72
    Last Post: 01-26-2009, 01:03 PM
  2. My C89 RANT!
    By evildave in forum C Programming
    Replies: 12
    Last Post: 12-07-2005, 10:15 PM
  3. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  4. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM