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<0>
时,会将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 - 啥时候实例化视图属性?