青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 23,  comments - 94,  trackbacks - 0
/************************************************************************/
/* Copyright (c) 2009, Roc King
All rights reserved.

Redistribution and use in source and binary forms,
    with or without modification, are permitted
    provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and other materials provided with the distribution.

3. Neither the name of the Tju nor the names of its contributors
    may be used to endorse or promote products derived from this software
    without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
    AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                                     
*/
/************************************************************************/


/**
這份代碼詳細介紹了使用SFINAE技術實現is_not_buildin_type的原理。
按順序由上往下閱讀即可。
*/

#include 
<stdio.h>
#include 
<iostream>


/** ------------------------------------------------------------------------ */
#define DEFINITION(prefix)          \
prefix none {};                     \
prefix data { 
int i; };             \
prefix function { 
void f(int ) {} };    \
prefix both { 
int i; double f() { return 0.0; } };

namespace structures { DEFINITION(struct) }
namespace s = structures;

namespace classes { DEFINITION(class) }
namespace c = classes;

namespace unions { DEFINITION(union) }
namespace u = unions;

#undef DEFINITION

/**
上面對class、struct、union分別定義了:
none        有數據成員,無成員函數
data        有數據成員,沒成員函數
function    無數據成員,有成員函數
both        有數據成員,有成員函數
*/

/** ------------------------------------------------------------------------ */

void test_pointer_to_data_member() {

    
// 一旦某個類型不是基本數據類型,就可以定義成員指針(數據成員指針,成員函數指針)。
    
// 即使它沒有數據成員或者成員函數。

    
// s::none 并沒有數據成員或者成員函數。
    int s::none::* p; //但是可以定義一個指向s的數據成員指針,只要類型不是void
    
// void s::none::* p2; //error C2182: 'p2' : illegal use of type 'void'

    
// 同時,在C++中,字面值0可以隱式轉換到任何指針類型。
    p = 0// ok
    double s::none::* p3 = 0// ok

    
// 但是,如果某類型沒有對應類型的數據成員,就不能用數據成員指針去指向它。
    int s::data::* p4 = 0;
    p4 
= &s::data::i;  // ok
    double s::data::* p5 = 0;
    
// p5 = &s::data::i;
    
// error C2440: '=' : cannot convert from 'int structures::data::* ' to 'double structures::data::* '

    (
void)p3; (void)p5;
}

// 這個是比較完整的測試
void test_pointer_to_data_member_integrate();


/** ------------------------------------------------------------------------ */

void test_pointer_to_member_function() {
    
// 同理,一旦某個類型不是基本類型,就可以定義指向該類型的成員函數的指針。
    
// 并且字面值0可以隱式轉換到該指針。

    
int (u::none::* p1)(void)  = 0;
    
double (u::none::* p2)(double= 0;

    
// 如果該類型確實有匹配的成員函數,可以使用該成員函數給指針賦值。
    double (u::both::* p3 )(void= &u::both::f;
    
void (u::function::* p4)(int= &u::function::f;

    
// 否則不能賦值
    
// double (u::both::* p5 )(void) = &u::function::f;
    
//error C2440: 'initializing' : cannot convert from 'void (__thiscall unions::function::* )(int)' to 'double (__thiscall unions::both::* )(void)'
    
// void (u::function::* p6)(int) = &u::both::f;
    
//error C2440: 'initializing' : cannot convert from 'double (__thiscall unions::both::* )(void)' to 'void (__thiscall unions::function::* )(int)'

    (
void)p1; (void)p2; (void)p3; (void)p4;
}

// 這個是比較完整的測試
void test_pointer_to_member_function_integrate();

/** ------------------------------------------------------------------------ */
/**
那么,測試一個類型是否是內建類型的“一個”方法就是
*/

namespace SFINAE {

    
class true_type { char dummy; true_type(); };
    
class false_type { char dummy[2]; false_type(); };
    
// sizeof(true_type)!=sizeof(false_type)

    template
<class C>
    true_type is_not_buildin_type_test(
int C::* pointer_to_data_member);

    template
<typename T>
    false_type is_not_buildin_type_test();

    
void test_theory() {
        
using namespace std;

        
/* 在當前名字空間下, is_not_buildin_type_test是2個函數模板的名字:
        template<class C>
        true_type is_not_buildin_type_test(int C::* pointer_to_data_member);
        (以下簡稱模板1)

        template<typename T>
        false_type is_not_buildin_type_test();
        (以下簡稱模板2)

        它們相互構成重載。
        
*/

        cout
<<sizeof( is_not_buildin_type_test<c::none>(0) )<<endl;
        
// 0 可以隱式轉化成 int c::none::* ,可以匹配模板1 (with C = c::none)

        
// 這里int是無關緊要的, 只要不是void就行
        
// 當然使用其他類型的數據成員指針 T C::* (T!=void)
        
// 或者成員函數指針進行測試 T (C::*)(paramter_list),也是可以的
        
// 只是int C::* 寫起來比較方便。

        
// 因為() 可以匹配任何類型的對象,
        
// 所以 0 也可以匹配模板2

        
// 又因為()處于重載選擇優先級中的最底層,所以最終匹配模板1。
        
// 注意,此處模板2不能使用(int),或者(T*)因為它的優先級高于(int C::*)


        cout
<<sizeof( is_not_buildin_type_test<double>(0) )<<endl;
        
// 0 不能隱式轉換成 int double::*,也就不能匹配模板1 ( with C=double )

        
// 但是還有一個“補救”的函數模板2,可以匹配任何類型的對象。
        
// 又因為SFINAE(Substitution failure is not an error)機制
        
// 所以對模板1的失敗的匹配并不報錯。
    }

    
// 還有一些細節
    
// 比如is_not_buildin_type_test并沒有實現。
    
// 但是因為它同時也沒有被調用, 而僅僅是用sizeof測試它的返回值,所以不算錯誤。
    
// 也防止了客戶無意調用這個函數。

    
// 如何得知哪個is_not_buildin_type_test被重載選中?
    
// 是通過返回值的大小不同來區分的。

    
// 所以就需要true_type和false_type這2個東西。
    
// 其實更合理的命名應該是small_type和big_type。
    
// 同時,它們聲明有私有的構造函數,并且不實現,防止客戶使用這2個類。

    
// 還因為is_not_buildin_type_test并沒有真正實現
    
// 也就沒有真正返回true_type或者false_type
    
// 所以沒有實現true_type和false_type的構造函數也沒關系。

    
// 一切都因為sizeof ……

    
/** -------------------------------------------------------------------- */
    
/**
    將這種方法再包裝一下
    (避免客戶去使用sizeof( xxx ) == sizeof( ture_type )等等)
    就得到
    
*/

    template
<typename T>
    
class is_not_buildin_type {
        is_not_buildin_type();
    
public:
        
enum { value =
            
sizeof(true_type)==sizeof( is_not_buildin_type_test<T>(0) ) };
    };
    
// 或者將true_type,false_type,定義為它的內嵌類型。
    
// 同時將is_not_buildin_type_test定義為它的靜態成員函數。

    template
<typename T>
    
class is_not_buildin_type2 {
        is_not_buildin_type2();

        
// 因為是內嵌的private,客戶不能訪問
        
// 所以可以隨意一點
        typedef char small_t;
        
struct big_t { small_t dummy[2]; };

        template
<typename U>
        
static big_t test(void (U::*)(shortfloat) );
        
// 只要是成員指針就ok,無論是數據成員指針還是成員函數指針。
        
// 也無論類型,簽名如何。

        template
<typename U>
        
static small_t test();
        
// 注意補救函數現在返回small_t

    
public:
        
// 但這也是無關緊要的,因為small_t和big_t只是告之哪個重載被選中的方式。
        
// 只要這里處理好對應就可以了。
        enum { value= sizeof(big_t)==sizeof( test<T>(0) ) };
    };

    
void test_wrapper() {
        
using namespace std;
        cout
<<is_not_buildin_type<c::data>::value<<endl;
        cout
<<is_not_buildin_type<u::both>::value<<endl;
        cout
<<is_not_buildin_type<float>::value<<endl;

        cout
<<is_not_buildin_type2<c::data>::value<<endl;
        cout
<<is_not_buildin_type2<u::both>::value<<endl;
        cout
<<is_not_buildin_type2<float>::value<<endl;
    }

    
// 一個更完整的測試
    void test_wrapper_integrate();
}

/** ------------------------------------------------------------------------ */
/**測試一個類型是否是內建類型的另一個方法,需要更少的技巧。*/

namespace partial_specialization {

    template
<typename T>
    
struct is_not_buildin_type { enum { value=true }; };
    
// T不是一個內建類型

    
// 除非
    template<>
    
struct is_not_buildin_type<int> { enum { value=false}; };
    
// T是int
    template<>
    
struct is_not_buildin_type<unsigned int> { enum { value=false}; };
    
// T是unsigned int
    
// .. more ..
}

int main()
{
    
using namespace std;
    test_pointer_to_data_member();
    test_pointer_to_data_member_integrate();
    test_pointer_to_member_function();
    test_pointer_to_member_function_integrate();

    cout
<<endl;
    SFINAE::test_theory();
    cout
<<endl;
    SFINAE::test_wrapper();
    cout
<<endl;
    SFINAE::test_wrapper_integrate();
}



void test_pointer_to_data_member_integrate() {
    
// to do
}
void test_pointer_to_member_function_integrate() {
    
// to do
}

namespace SFINAE {
    
void test_wrapper_integrate() {
        
// to do
    }
}

這個代碼已經能很完美的解釋了~
今天看了C++ Templates 的15章.. 收獲頗多.. 以前的很多疑惑都比較開朗了~

posted on 2009-03-16 23:32 Charlie 侯杰 閱讀(2675) 評論(3)  編輯 收藏 引用
by Charlie
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            夜夜精品视频一区二区| 999亚洲国产精| 牛人盗摄一区二区三区视频| 欧美在线视频一区| 欧美一区二区三区在线视频 | 欧美va亚洲va国产综合| 女生裸体视频一区二区三区| 欧美岛国激情| 日韩一二三区视频| 亚洲欧美电影在线观看| 久久国产黑丝| 欧美不卡三区| 国产精品久久久一区二区| 国产精品丝袜白浆摸在线| 好男人免费精品视频| 亚洲精品乱码久久久久久日本蜜臀 | 午夜精品一区二区三区四区| 久久精品人人做人人爽电影蜜月 | 一本色道久久综合亚洲精品不卡 | 日韩午夜电影av| 午夜精品福利在线| 欧美激情乱人伦| 亚洲一区二区在线看| 久久综合伊人| 国产精品一区二区三区久久| 亚洲国产精品福利| 午夜欧美不卡精品aaaaa| 欧美二区不卡| 小黄鸭精品aⅴ导航网站入口| 老司机成人网| 久久国产一区| 亚洲一二三级电影| 免费久久99精品国产自在现线| 亚洲国产日韩欧美| 亚洲一区在线播放| 欧美韩日一区| 一区在线影院| 欧美一区二区在线视频| 亚洲人体大胆视频| 美女精品视频一区| 国产一区二区三区直播精品电影| 亚洲作爱视频| 欧美激情视频网站| 久久久精品免费视频| 国产精品五区| 亚洲欧美国产日韩中文字幕| 亚洲国产另类 国产精品国产免费| 久久av一区二区三区漫画| 国产精品欧美日韩一区| 一区二区三区不卡视频在线观看 | 亚洲欧美经典视频| 欧美日韩在线大尺度| 亚洲伦理精品| 欧美成年人视频网站| 久久精品国产2020观看福利| 国产精品视频自拍| 先锋影音国产一区| 亚洲自啪免费| 国产精品夜色7777狼人| 性欧美暴力猛交另类hd| 中文一区字幕| 欧美日韩综合视频| 亚洲主播在线观看| 亚洲一区二区三区激情| 国产精品私房写真福利视频 | 欧美视频一区在线观看| 日韩午夜中文字幕| 亚洲精品影视| 欧美先锋影音| 亚洲欧美日韩系列| 欧美一级成年大片在线观看| 国产一区二区三区高清播放| 久久青草久久| 久热国产精品| 夜夜嗨av一区二区三区| 亚洲视频国产视频| 国产自产女人91一区在线观看| 久久青草福利网站| 欧美大片在线看免费观看| 日韩一级片网址| 亚洲图中文字幕| 国产一区二区激情| 亚洲高清不卡av| 国产精品v欧美精品v日本精品动漫| 午夜欧美电影在线观看| 欧美午夜在线一二页| 亚洲在线网站| 久久不射中文字幕| 亚洲精美视频| 亚洲视频一起| 在线成人国产| 一区二区精品| 国语自产偷拍精品视频偷 | 国产日韩精品视频一区二区三区| 久久视频一区二区| 欧美另类变人与禽xxxxx| 羞羞视频在线观看欧美| 久久综合婷婷| 香蕉久久夜色精品| 欧美 日韩 国产一区二区在线视频 | 欧美一区二区精品| 久久九九国产精品| 亚洲视频在线观看一区| 午夜精品福利一区二区蜜股av| 尤物九九久久国产精品的特点| 亚洲免费高清| 亚洲电影欧美电影有声小说| 中文亚洲欧美| 亚洲美女一区| 欧美在线视屏| 亚洲欧美综合一区| 欧美激情精品久久久久久久变态 | 欧美一级播放| 男人天堂欧美日韩| 久久男人av资源网站| 国产精品久久久久久妇女6080| 欧美成在线观看| 国产日韩三区| 一区二区三区波多野结衣在线观看| 狠狠色香婷婷久久亚洲精品| 一区二区三区久久| 9l国产精品久久久久麻豆| 久久深夜福利| 久久婷婷麻豆| 国产一区二区三区电影在线观看| 国产精品99久久久久久久久| 亚洲欧洲一二三| 美女精品网站| 欧美激情五月| 亚洲激情成人| 久久夜色精品国产欧美乱| 久久久xxx| 国产一级一区二区| 欧美一区二区三区四区在线观看地址| 小黄鸭精品aⅴ导航网站入口| 欧美视频在线观看免费网址| 亚洲激情婷婷| 一本色道久久综合亚洲精品按摩 | 亚洲国产婷婷香蕉久久久久久| 永久555www成人免费| 久热国产精品| 亚洲精品一区二区三区蜜桃久| 久久尤物视频| 免费日韩av电影| 韩日欧美一区二区| 久久久国产精品一区二区中文 | 一区二区三区四区国产| 在线视频日本亚洲性| 欧美网站在线| 亚洲一区在线免费| 久久精品综合网| 影音先锋另类| 欧美freesex8一10精品| 亚洲国产精品va在看黑人| 日韩视频精品在线观看| 欧美精品九九| 亚洲午夜精品视频| 久久精品99国产精品| 精品福利av| 欧美日韩第一页| 午夜国产精品视频| 麻豆精品在线播放| 日韩午夜激情av| 国产精品免费在线| 久久久久久久久久看片| 亚洲人人精品| 久久久久久97三级| 99成人在线| 国产日韩在线看片| 欧美国产综合一区二区| 翔田千里一区二区| 亚洲国产精品久久久久久女王| 亚洲特色特黄| 亚洲丁香婷深爱综合| 国产精品白丝jk黑袜喷水| 久久精品国产99国产精品澳门| 欧美国产91| 欧美一区在线视频| 亚洲人成人77777线观看| 国产精品久久一区主播| 免费成人黄色| 亚洲综合激情| 亚洲日韩第九十九页| 久久精品系列| 亚洲视频电影图片偷拍一区| 一区二区三区在线观看国产| 欧美日韩视频在线一区二区 | 欧美国产亚洲视频| 欧美在线观看视频一区二区三区 | 国产精品美女久久久久aⅴ国产馆| 欧美一区二区在线| 一区二区三区色| 亚洲激情国产| 欧美电影免费观看高清| 久久福利影视| 午夜精品亚洲一区二区三区嫩草| 亚洲精品视频在线| 亚洲国产精品99久久久久久久久| 国产欧美日韩综合一区在线观看| 欧美视频一区二区三区|