【问题标题】:complex C++ template syntax复杂的 C++ 模板语法
【发布时间】:2010-12-06 05:27:07
【问题描述】:

加入 SO 后,每当我打开讨论模板的主题时,我都会经常看到这种语法。我尝试在谷歌上搜索,但徒劳无功。

template<typename T>
char (&f(T[1]))[1]; //what is it? what is the use of '[]' brackets and the integer in it?

template<typename T>
char (&f(...))[2]; //not this either

int main() { char c[sizeof(f<void()>(0)) == 2]; } // and this?

从这里:SFINAE with invalid function-type or array-type parameters?

请解释我放置 cmets 的 3 行。我特别想了解语法。我们可以只在模板中使用这样的语法吗?

【问题讨论】:

    标签: c++ templates syntax


    【解决方案1】:

    以下两个是等价的

    // 1
    template<typename T>
    char (&f(...))[2]; 
    
    // 2
    typedef char rettype[2];
    template<typename T>
    rettype &f(...);
    

    您之前可能已经使用函数指针看到过这种模式

    char (*XXX)();
    

    现在只需将() 替换为[N] 以创建数组而不是函数部分,并将@​​987654325@ 替换为&amp; 以创建引用而不是指针,并将XXX 替换为a函数声明器。然后你会得到一个函数,它返回对大小为N 的数组的引用。


    您可能想查看man signal,它包含一个类似类型的函数声明。如果你取出实际声明函数的内部声明符,你会得到相同的模式

    void (* signal(int sig, void (*func)(int)) )(int);
    //      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ take out that 
    

    它将返回一个指向函数的指针,该函数接受int 并返回void,如该手册页中所述。


    以下只是产生编译器错误的一种方法如果某些条件不满足。 如果测试foo == 2 变成false,则创建的数组大小为零,这在C++ 中是非法的,并且会产生编译时错误。如果它的计算结果为真,除了声明的数组之外什么都不会发生。

    char c[some silly condition here];
    

    【讨论】:

    • 很好的解释,谢谢。如果那个愚蠢的条件创建了一个大小为零的数组,那你为什么要设置这个条件?
    • 因为其目的是利用数组大小​​的无效性来防止编译某些特定的代码片段——例如,为要特别处理的特定类型的某些模板的实例化。
    • @Pointer:这是一个被称为“编译时断言”的概念。 “正常”assert() 在运行时检查布尔条件。使用此方法,您可以在编译时检查布尔条件。例如,char c[CHAR_BIT==8] 明确表示您的程序无法处理具有 CHAR_BIT==9 的编译器
    • @karl,@MSalters。请解释一下'T[5]'是什么意思?是不是也无效?比如说,T 是 int,那么 int[5] 是什么意思呢?我尝试写一个func(int[5] arg),它给出了错误。
    猜你喜欢
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    相关资源
    最近更新 更多