c++啥时候实例化方法?

Posted

技术标签:

【中文标题】c++啥时候实例化方法?【英文标题】:When c++ instantiating method?c++什么时候实例化方法? 【发布时间】:2019-11-20 21:59:58 【问题描述】:

我正在尝试用 gcc 和 clang 编译这段代码:

#include <iostream>
#include <type_traits>


template<int N>
struct Test

    template<typename = std::enable_if_t<N == 1, bool>>
    void func()
    
        std::cout << "Test::func" << std::endl;
    
;

int main()

    Test<0> t;

    //t.func();

所以,我有一个错误:

error: no type named 'type' in 'std::__1::enable_if<false, bool>'; 'enable_if' cannot be used to 
disable this declaration
template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;

但是,如果我使用 vc++ 编译该代码,则不会出现错误。 那么,哪个编译器根据 c++ 标准解决了这个问题?

【问题讨论】:

【参考方案1】:

GCC 和 Clang 在这里是正确的。

当您编写Test&lt;0&gt; 时,会将N 替换为0。在func 的声明中,std::enable_if_t 将尝试访问不存在的成员::type。这是一个错误,因为该成员不存在并且您不能拥有这样的声明。

SFINAE 的工作方式是,在重载解析期间,当编译器执行模板参数推导时,如果模板中的参数替换失败,您不会收到错误,并且函数从潜在的重载集中被丢弃。在您的示例中,没有模板参数推导。 N 已经从类模板中得知,因此在重载决议开始之前,func 的声明格式不正确。

您的用例的潜在解决方法是:

template<int M = N, typename = std::enable_if_t<M == 1, bool>>
void func()

    std::cout << "Test::func" << std::endl;

这样,func 现在依赖于函数模板参数 M,并且 SFINAE 可以按预期工作。

【讨论】:

嗯...我想,如果我不使用函数func,那么编译器就不会为该函数实例化并生成代码。 “请注意,代码仅针对被调用的模板(成员)函数进行实例化。对于类模板,成员函数仅在使用时才被实例化。” - 这是来自 C++ Templates The Complete Guide 2nd 的引文版。 模板确实不会被实例化,但它仍然需要是一个有效的函数模板声明。在这种情况下不会,声明格式不正确。您可以在未调用的模板函数的 body 中包含无效代码,但在其声明中没有(除非 SFINAE 应用,在这种情况下它不存在,因为没有替换)。跨度>

以上是关于c++啥时候实例化方法?的主要内容,如果未能解决你的问题,请参考以下文章

UIviewcontroller - 啥时候实例化视图属性?

Java方法内创建对象实例后,啥时候释放内存(引

java中实例化方法是啥意思

c# 中类的实例化

如何判断java的一个类能否继承另一个类? 还有在new实例化一个对象时候有啥限制,

java中实例化对象和创建对象这两者有啥区别希望大神用代码举例说明便于理解,小弟谢谢了!