编译阶段侦测相同性

原创 2007年09月30日 01:32:00
Loki中中有一个类似这样的类用以在编译阶段侦测两个类型是否具有可转换性:
template    <typename T,typename U>
class TestType
...{
    typedef    
char            Small;
    typedef    
struct...{char buf[2];}    Big;
    Small    Test(T);
    Big        Test(...);
    T        MakeT();
public:
    
enum    ...{exist = (sizeof(Small) == sizeof(Test(MakeT())))};
}
;

其中比较有新意的一点就是稻草人函数MakeT的使用,它解决了在T无法被构造的时候这个测试类无法使用的问题,但是却有一个小小的问题。那就是当T是数组的时候,函数是不允许回传数组的,所以这个类又无法使用了,可能作者未考虑到这种情况,毕竟很少有人变态到把完整的数组信息传来传去,但是我却在实际使用中遇到了。


template    
<typename T,typename U>
class TestType
...{
    typedef    
char            Small;
    typedef    
struct...{char buf[2];}    Big;
    Small    Test(T);
    Big        Test(...);
    T        MakeT();
public:
    
enum    ...{exist = (sizeof(Small) == sizeof(Test(MakeT())))};
}
;

class Base...{};
template    
<class T>
void    doSomething(T& data)
...{
    TestType
<T,Base[100]>::exist;
}

int _tmain(int argc, _TCHAR* argv[])
...{
    Base    buf[
100];
    doSomething(buf);
    
return 0;
}

首先我使用了模板策略获得了函数传来的完整数组信息,然后为了确定数组是否是特定一个数组类型的时候,我想到了这个测试类,它报错了,编译器抱怨说函数回传了一个数组。

从我的认知范围里,我无法获得一个同样封装模式但可以解决这个问题的类,也许你想到这样:

template    <typename T,typename U>
class TestType
...{
    typedef    
char            Small;
    typedef    
struct...{char buf[2];}    Big;
    Small    Test(T);
    Big        Test(...);
    T        MakeT();
    template    
<typename    M>
    GetRawType(M)
    
...{
        
return    MakeT();
    }

    template    
<typename    M>
    GetRawType(M[])
    
...{
        
return    M;
    }
;

public:
    
enum    ...{exist = (sizeof(Small) == sizeof(Test( GetRawType(T()) )))};
}
;

但这成了鸡生蛋还是蛋生鸡的问题。

我尝试了很多办,包括类型选择和试图利用转掉const的策略转掉[],但是都没有成功,buf[100]已经在模板替换的时候被作为一个独立的类型了,我的类型选择必须得做成这样才可以运作:

template    <typename T>
struct    IsArray
...{
    typedef    T    Result;
    
enum    ...{result = 2};
}
;
template    
<typename T>
struct    IsArray<T[100]>
...{
    typedef    T    Result;
    
enum    ...{result = 1};
}
;

template    
<typename    T>
void    doSomething(T& buf)
...{
    cout
<<IsArray<T>::result<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
...{
    
char    buf[100];
    doSomething(buf);
    
return 0;
}

注意我已经固化了这个数组T[100],这样的一个模板是没有任何实用价值的。

但是,到现在为止,我已有的知识无法让我封装出一个类库性质的东西,可是却可以得到这类问题的解法,当是真的要ASSERT某个特定类型是否为特定的具有完整信息的数组的时候,你可以这样:

template    <typename T>
struct    IsArray
...{
    
enum    ...{isarray = false};
}
;
template    
<typename T>
struct    IsArray<T[100]>
...{
    
enum    ...{isarray = true};
}
;

template    
<typename    T>
void    doSomething(T& buf)
...{
    MyAssert(IsArray
<T>::isarray);
}

int _tmain(int argc, _TCHAR* argv[])
...{
    
char    buf[100];
    doSomething(buf);
    
return 0;
}

注意这里的MyAssert是使用模板做成的编译期的assert功能。

这样验证特定数据是否是数组的问题得到了一个解法,虽然没有现成的类可用,但是毕竟你碰到这种情况的时候不多,而且我真的无法想到更好的办法了。

运行时异常与受检异常的异同

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无...
  • beliefyou8
  • beliefyou8
  • 2016年07月25日 11:44
  • 1242

gcc编译程序的四个阶段(预处理-编译-汇编-链接)

gcc的编译流程分为四个步骤,分别为: ・ 预处理(Pre-Processing) ・ 编译(Compiling) ・ 汇编(Assembling) ・ 链接(Linking) 下面就具体来查看一下g...
  • qq_31108501
  • qq_31108501
  • 2016年07月06日 20:08
  • 2124

需求评审阶段和设计评审阶段测试人员该做什么呢

大家都知道如果能把缺陷扼杀在编码之前可以节约很多成本,缺陷发现越晚花费的成本越高,尤其是设计上的缺陷如果到了编码后期甚至即将上线才发现也许会导致整个项目失败。所以现在越来越重视需求评审和设计评审,在前...
  • u012150264
  • u012150264
  • 2016年05月18日 15:00
  • 1435

loaderrunner关于事件侦测为0的解决办法

.此处暂时抛开安装的问题,解决事件侦测为0的问题 问题现象:当在loadrunner创建好脚本指定对某个网页服务进行侦测,点击确定的时候,弹出来一个SQL Studio的调试框,说要IE需要调试...
  • liao_huan
  • liao_huan
  • 2011年09月21日 17:09
  • 577

USB自动侦测USB盘符

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; ...
  • qq_35893094
  • qq_35893094
  • 2017年06月05日 07:16
  • 100

javascript 特征侦测技术

这种新式的技术最先由jquery搞出来的,接着prototype与mootools都支持了。这技术兴起的原因是浏览器嗅探技术是不太可靠,如useragent很容易被伪造,如ie8的useragent就...
  • javazhuanzai
  • javazhuanzai
  • 2012年01月10日 04:30
  • 180

Qt5自带串口调试 --使用signal接收数据,自动侦测端口列表

Qt5自带串口初步用一下感觉还不错。 调试记录 .pro文件增加 QT += serialport .h文件增加 #include #include private slo...
  • yh_1988
  • yh_1988
  • 2014年12月08日 14:39
  • 11887

在C++中侦测内嵌型别的存在(rev#2)

在C++中侦测内嵌型别的存在(rev#2) http://blog.csdn.net/pongba/article/details/82783   动机(Motivation) 假...
  • zdy0_2004
  • zdy0_2004
  • 2015年01月25日 03:02
  • 251

如何用UIGestureRecognizer去侦测使用者输入

在3.2以前我们要用到UITouch跟用户互动,大部分都是通过UIResponser四种methods - (void)touchesBegan:(NSSet *)touches withEve...
  • zhanglei5415
  • zhanglei5415
  • 2011年10月11日 17:06
  • 12134

探究影像辨識裡的臉部偵測技術(二)

http://www.compotech.com.tw/articleinfo.php?id=9389 探究影像辨識裡的臉部偵測技術(...
  • rocky69
  • rocky69
  • 2012年09月23日 06:55
  • 18917
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:编译阶段侦测相同性
举报原因:
原因补充:

(最多只允许输入30个字)