1.深入浅出C++模板元编程(3)
2.fortran与matlab究竟哪个好?
3.C++ BootSpiritåºè¯¥å¦ä½ä½¿ç¨
深入浅出C++模板元编程(3)
1. 在前文中,模p模我们已经了解了SFINAE及其在函数重载中的板元编程板元编程应用。
2. 本文将深入探讨如何使用expression SFINAE检测类的源码构造函数特性,特别是模p模默认构造函数的检查。
3. 在C++中,板元编程板元编程Unevaluated Expression如typeid、源码精易源码sizeof、模p模noexcept和decltype,板元编程板元编程它们操作的源码表达式不会实际计算。
4. 例如,模p模sizeof(std::cout&)实际上并不执行输出,板元编程板元编程只是源码获取表达式的类型信息。
5. 这些操作符在编译时提供了对表达式类型进行检查但不执行的模p模最小uboot源码能力,被称作"检视"而非计算。板元编程板元编程
6. 在构造类对象时,源码即使在unevaluated context中,编译器会检查是否正确调用构造函数,包括析构函数。
7. 比如,atomic分析源码尝试用一个无析构函数的类no_dtor构造一个对象,会因sizeof表达式中的错误而报错。
8. 对于C风格数组和std::vector,动态扩容的数组允许存放没有默认构造函数的元素,而C风格数组则要求元素能段裂被默认构造。
9. 我们可以通过元编程,vue插槽源码结合decltype进行SFINAE,来检测类是否具有默认构造函数。
. 例如,通过尝试构造一个默认值,如果编译器可以接受,握好闭即表示有默认构造函数,vue源码展示否则为错误。
. 元函数try_construct采用不同的重载版本,使用std::declval提供未被构造的值,避免直接调用构造函数,使得检测更为灵活。
. 通过编译器检查这些表达式,我们能得到类的构造函数属性信息。
. 进一步,std::declval的使用简化了我们提供构造参数的方式,尽管初始化语法复杂,但通过这个函数,我们可以优雅地处理检测任意类型构造函数的能力。
. 然而,这些方法仅作为理解原理的工具,不建议直接用于生产代码,因为它们缺乏标准库的完整性和优化。
. 最后,我们将继续探索void_t和更高级的SFINAE技巧,如concept库的实现,以提升代码的简洁性和功能性。
fortran与matlab究竟哪个好?
.
Fortran无疑是最快的,看看
超级计算机
上用的是什么就知道了。
即使是C语言,在科学
并行计算
领域也远远比不上Fortran的速度,
C++
模板
元
编程技术
勉强可以和Fortran一拼。
但是Fortran学起来比Matlab慢,写程序也比Matlab慢,
所以平时做一些小问题完全适于用Matlab而不是Fortran
只有很大规模的(一天乃至几十天)运算量,才有必要换Fortran
.
C++ BootSpiritåºè¯¥å¦ä½ä½¿ç¨
çä¸é¢ç代ç ï¼è¿æ¯å ç¼ç¨çèµ·æºï¼
// Prime number computation by Erwin Unruh
template <int i> struct D { D(void*); operator int(); };
template <int p, int i> struct is_prime {
enum { prim = (p==2) || (p%i) && is_prime<(i>2?p:0), i-1> :: prim };
};
template <int i> struct Prime_print {
Prime_print<i-1> a;
enum { prim = is_prime<i, i-1>::prim };
void f() { D<i> d = prim ? 1 : 0; a.f();}
};
template<> struct is_prime<0,0> { enum { prim=1}; };
template<> struct is_prime<0,1> { enum { prim=1}; };
template<> struct Prime_print<1> {
enum { prim=0};
void f() { D<1> d = prim ? 1 : 0; };
};
#ifndef LAST
#define LAST
#endif
main() {
Prime_print<LAST> a;
a.f();
}
å¨GNU C++ (MinGW Special) 3.2ä¸ç¼è¯è¿æ®µç¨åºæ¶ï¼ç¼è¯å¨å°ä¼ç»åºå¦ä¸åºéä¿¡æ¯ï¼ä»¥åå ¶å®ä¸äºä¿¡æ¯ï¼ç®çèµ·è§ï¼å®ä»¬è¢«å é¤äºï¼ï¼
Unruh.cpp:: initializing argument 1 of `D<i>::D(void*) [with int i = ]'
Unruh.cpp:: initializing argument 1 of `D<i>::D(void*) [with int i = ]'
Unruh.cpp:: initializing argument 1 of `D<i>::D(void*) [with int i = ]'
Unruh.cpp:: initializing argument 1 of `D<i>::D(void*) [with int i = 7]'
Unruh.cpp:: initializing argument 1 of `D<i>::D(void*) [with int i = 5]'
Unruh.cpp:: initializing argument 1 of `D<i>::D(void*) [with int i = 3]'
Unruh.cpp:: initializing argument 1 of `D<i>::D(void*) [with int i = 2]'
è¿ä¸ªä¾åå±ç¤ºäºå¯ä»¥å©ç¨æ¨¡æ¿å®ä¾åæºå¶äºç¼è¯ææ§è¡ä¸äºè®¡ç®ãè¿ç§éè¿æ¨¡æ¿å®ä¾åèæ§è¡çç¼è¯æ计ç®ææ¯å³è¢«ç§°ä¸ºæ¨¡æ¿å ç¼ç¨ã
模æ¿å ç¼ç¨ï¼Template Metaprogrammingï¼æ´åç¡®çå«ä¹åºè¯¥æ¯âç¼âå¯ä»¥ç¼ç¨åºçâç¨åºâï¼è模æ¿å ç¨åºï¼Template Metaprogramï¼åæ¯ââå¯ä»¥ç¼ç¨åºçâç¨åºâãä¹å°±æ¯è¯´ï¼æ们ç»åºä»£ç ç产çè§åï¼ç¼è¯å¨å¨ç¼è¯æ解éè¿äºè§å并çææ°ä»£ç æ¥å®ç°æ们é¢æçåè½ã