Thread: Templates: type deduction question

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Templates: type deduction question

    Consider:
    Code:
    template<typename T>
    struct bar
    {
    	typedef T type;
    };
    
    template<typename T>
    void foo(T& t_) {}
    
    template<typename T>
    void foo2(typename bar<T>::type t_) {}
    
    int main()
    {
    	int n;
    	foo(n);
    	foo2(n);
    }
    foo(n) will compile, but foo2(n) will not compile.
    I'm a little fuzzy on these rules. Why is it so, and what can be done about it?
    Last edited by Elysia; 06-04-2010 at 11:55 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It's probably to do with a thing called non-deduced context. Basically the function receives an argument of some type, how do you expect it to figure out what the template parameters should be so that it could instantiate it and see if it matches the inner name?

    I'd probably go with

    Code:
    template <class GraphType>
    GraphType foo(const GraphType& t);
    where all the other types can be found out by requiring suitable typedefs from acceptable GraphTypes.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The main problem here is that I have lots of template parameters that needs to be forwarded. It quickly becomes a mess. One little change somewhere breaks 1000s of lines of code (that's an exaggeration, but still).
    So, to solve this, I keep a centralized place of typedefs and macros to shorten the types and whatnot. The problem with typedefs is that I can't create them on a global level since they depend on template parameters.
    For example,
    typedef Graph<NegativeWeight, DirectedType, NodeT, EdgeT> Graph_t;
    Not going to happen locally. So I made a struct with these typedefs and inherited from it.
    But that creates problems for global functions that uses these types, so I made macros too.

    Now, I want to minimize the places I have to change if I add a parameter and change a type, etc, so I want the macros and the typedefs to be the same thing. Rely on each other, so to speak, so I don't have to change both.

    At first I thought I could implement the macros as the typedefs in the struct, but obviously this didn't work so well (as seen by the example above).
    So right now I removed all the typedefs and go 100% with macros.
    I dunno if it's a good idea or not.

    Code:
    #ifndef GraphTraits_201540_H
    #define GraphTraits_201540_H
    
    #define DIRECTED_TYPE						template<bool, typename, typename> class
    #define GRAPH_TPL							template<bool NegativeWeight, DIRECTED_TYPE DirectedType, typename NodeT = void, typename EdgeT = void>
    #define EDGE_TPL							template<bool NegativeWeight, DIRECTED_TYPE DirectedType, typename NodeT, typename EdgeT>
    #define DIRECTED_TPL						template<bool NegativeWeight, typename NodeT, typename EdgeT>
    #define GENERATE_MINIMUM_SPANNING_TREE_TPL	template<DIRECTED_TYPE DirectedType, typename NodeT, typename EdgeT>
    
    #define TPL_LIST				NegativeWeight, DirectedType, NodeT, EdgeT
    #define DIRECTED_TPL_LIST		NegativeWeight, NodeT, EdgeT
    #define DIRECTED_TPL_LIST_2(x)	NegativeWeight, x, NodeT, EdgeT
    #define NEG_TPL_LIST			true, DirectedType, NodeT, EdgeT
    #define PTR_LIST				ptr_thread_dangerous, 32
    
    #define DIRECTED_NODE_BASE(x)	Node< DIRECTED_TPL_LIST_2(x) >
    #define DIRECTED_EDGE_BASE(x)	Edge< DIRECTED_TPL_LIST_2(x) >
    #define DIRECTED_TYPE_BASE(x)	DirectedBase< DIRECTED_TPL_LIST_2(x) >
    
    #define DIRECTED_TYPE_BASE_T	DIRECTED_TYPE_BASE(DirectedType)
    #define DIRECTED_BASE_T			DIRECTED_TYPE_BASE(::Directed)
    #define UNDIRECTED_BASE_T		DIRECTED_TYPE_BASE(::Undirected)
    #define DIRECTED_TYPE_T			DirectedType< DIRECTED_TPL_LIST >
    #define DIRECTED_NODE_T			DIRECTED_NODE_BASE(::Directed)
    #define UNDIRECTED_NODE_T		DIRECTED_NODE_BASE(::Undirected)
    #define DIRECTED_EDGE_T			DIRECTED_EDGE_BASE(::Directed)
    #define UNDIRECTED_EDGE_T		DIRECTED_EDGE_BASE(::Undirected)
    #define NODE_T					Node< TPL_LIST >
    #define NODE_NEG_T				Node< NEG_TPL_LIST >
    #define NODE_PTR_T				mad_shared_ptr< NODE_T, PTR_LIST >
    #define NODE_PTR_NEG_T			mad_shared_ptr< NODE_NEG_T, PTR_LIST >
    #define EDGE_T					Edge< TPL_LIST >
    #define GRAPH_T					Graph< TPL_LIST >
    #define GRAPH_NEG_T				Graph< NEG_TPL_LIST >
    #define WEIGHT_T				typename CommonGraphTraits<NegativeWeight>::weight_t
    
    template<bool NegativeWeight> struct CommonGraphTraits { typedef int weight_t; };
    template<> struct CommonGraphTraits<false> { typedef unsigned int weight_t; };
    
    template<typename T> struct DataTrait { T m_Data; };
    template<> struct DataTrait<void> { };
    
    #endif // GraphTraits_201540_H
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The reason is that, given an argument of type int, the compiler has no way of understanding that it must call foo2<int>(typename bar<int>::type).

    You can help the compiler by calling it using
    Code:
    foo2<int>(n);
    which gives the compiler a direct hint about what type T is.

    As to your macros .... I haven't even managed to wrap my mind around those.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by grumpy View Post
    As to your macros .... I haven't even managed to wrap my mind around those.
    Well, feel free to take your time... or not. Absolutely no need to do so.
    I think I am going with the macro model some template programming in the future (instead of typedefs) for common types that needs to be used globally.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you check what is wrong with this code
    By Ron in forum C++ Programming
    Replies: 4
    Last Post: 08-01-2008, 10:59 PM
  2. Replies: 0
    Last Post: 03-20-2008, 07:59 AM
  3. qwerty/azerty keyboard type problem + question about loop.
    By Robin Hood in forum C++ Programming
    Replies: 9
    Last Post: 07-22-2002, 01:03 PM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM
  5. Newbies question about the integer type
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 10-17-2001, 08:09 PM