C++ Template Corner Cases

各位读者,很抱歉这篇文章是英文的,我当初做笔记的时候,写成英文了,这样才可以在同事之间交流。而现在确实没时间翻译过来了,还望大家理解,谢谢!

Following are some corner cases of C++ template features. A lot of the text is simply extracted from "C++ Templates: The Complete Guide", with some of my personal understanding. These features are trivial and easily neglected, but you should have some impression to them in case you run into troubles caused by the neglect.

I made my notes in English, and I don't bother to translate them into Chinese, forgive my laziness. :)



0. use "typename" to extract type defined within a type parameter, like this: typename T::iterator itr; otherwise the 'itr' is treated as a data member of T.

1. zero initialization
When using a var x of type T, we MUST initialize it like this: T x = T(); so that when T is a primitive type, x can also be initialized with 0, or NULL (when T is a pointer type). Of course we must make sure
when T is a class type, it has a default constructor. Simply using T x; can't initialize x when T is a primitive type.

2. .template

The .template Construct
A very similar problem was discovered after the introduction of typename. Consider the following example using the standard bitset type:

template<int N>
void printBitset (std::bitset<N> const& bs)
{
    std::cout << bs.template to_string<char,char_traits<char>,
                                       allocator<char> >();
}
The strange construct in this example is .template. Without that extra use of template, the compiler does not know that the less-than token (<) that follows is not really "less than" but the beginning of a template argument list. Note that this is a problem only if the construct before the period depends on a template parameter. In our example, the parameter bs depends on the template parameter N.

3. char star string type at reference type parameter
Suppose we have a string str: char str[32]; The type of 'str' symbol is "a char string" and "of 32 chars long". similarly the literal "abc" 's type is: " a char string" and "of 3 chars long",
that is, the "type" information consists of both "base type", which is "char", and "length", which is 32 here. So
such a string is of different type to a char* pointer, such as char*p; , a type conversion is done if passing a string literal as argument to a function with char* formal parameter.

template <typename T>
inline T const& max (T const& a, T const& b)
{
    return a < b ? b : a;
}

So when we use max("abc", "def") to call above function, it is OK. but if we use max("abc", "defg") to call it, it is wrong, because "abc" and "defg" are of different types --- the length is different. And automatical type conversion is not done for reference types here.

This means that the above array 'str', and string literals like "abc", is not of the same type as "char *pstr;", as most people may believe. Actually it takes a conversion to convert 'str' array or the string literals to a 'char*' type. However, during template argument deduction array-to-pointer conversion (often called decay) occurs only if the parameter does not have a reference type. Thus we have the above issue. And if we don't use reference in above code, like this:
template <typename T>
inline T max (T a, T b)
{
    return a < b ? b : a;
}

Both max("abc", "def") and max("abc", "defg") can build OK, since a automatic conversion from string literal to char* is done, so finally we have the same type 'char*' as T.

4. template template types
After reading the whole lot of text in the book, I realized that this is really a very particular feature, too complicated and restricted to use widely.
Though, since it is a very recently added new C++ template feature, it can be used in your configure script to test whether your compiler conforms to
C++ language standard. The piece of code in the book can directly be used in your m4 file for configure to use.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ templates are a powerful feature of the C++ programming language that allow generic programming. Templates enable the creation of functions and classes that can work with different data types without the need for separate implementations for each data type. Templates are defined using the keyword "template" followed by a list of template parameters enclosed in angle brackets "< >". The template parameters can be either type parameters or non-type parameters, depending on whether they represent a data type or a value. For example, a type parameter might be used to specify the data type of a container class, while a non-type parameter might be used to specify the size of an array. Here is an example of a simple function template that returns the maximum of two values: ```c++ template<typename T> T max(T a, T b) { return a > b ? a : b; } ``` In this example, the "typename" keyword is used to indicate that T is a type parameter. The function can be used with any data type for which the ">" operator is defined. Templates can also be used to define class templates, which are similar to regular classes but can work with different data types. Here is an example of a simple class template for a stack: ```c++ template<typename T> class Stack { public: void push(T value); T pop(); private: std::vector<T> data_; }; template<typename T> void Stack<T>::push(T value) { data_.push_back(value); } template<typename T> T Stack<T>::pop() { T value = data_.back(); data_.pop_back(); return value; } ``` In this example, the class template is defined with a single type parameter T. The member functions push and pop are defined outside the class definition using the scope resolution operator "::". Templates are a powerful tool that can greatly simplify code and make it more reusable. However, they can also be complex and difficult to debug. It is important to use templates judiciously and to thoroughly test them with a variety of data types.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值