大佬教程收集整理的这篇文章主要介绍了c – 尾随返回类型和标记分派,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
#include <String> #include <iostream> using namespace std; namespace Params { struct t_param1{}; struct t_param2{}; }; template<typename t_detail> struct SELEct; template<> struct SELEct<Params::t_param1> {using choice = Params::t_param1;}; template<> struct SELEct<Params::t_param2> {using choice = Params::t_param2;}; class Tester { private: using t_uint32 = uint32_t; using t_String = String; private: t_uint32 m_param1; // t_String m_param2; private: template<typename t_entity> void assign(const Params::t_param1&,t_entity&& entity); template<typename t_entity> void assign(const Params::t_param2&,t_entity&& entity); auto access(const Params::t_param1&) -> decltype(m_param1); // auto access(const Params::t_param2&) -> decltype(m_param2); public: template<typename t_detail,typename t_entity> void assign(t_entity&& entity); template<typename t_detail> auto access() -> decltype(access(typename SELEct<t_detail>::choice())); }; template<typename t_detail,typename t_entity> void Tester::assign(t_entity&& entity) { assign(typename SELEct<t_detail>::choice(),entity); } template<typename t_entity> void Tester::assign(const Params::t_param1&,t_entity&& entity) { m_param1 = entity; cout << "Assigned m_param1 with " << entity << endl; } /* template<typename t_entity> void Tester::assign(const Params::t_param2&,t_entity&& entity) { m_param2 = entity; cout << "Assigned m_param2 with " << entity << endl; } */ template<typename t_detail> auto Tester::access() -> decltype(access(typename SELEct<t_detail>::choice())) { return(access(typename SELEct<t_detail>::choice())); } auto Tester::access(const Params::t_param1&) -> decltype(m_param1) { return(m_param1); } /* auto Tester::access(const Params::t_param2&) -> decltype(m_param2) { return(m_param2); } */ int main() { auto tester = Tester(); tester.assign<Params::t_param1>(79); // tester.assign<Params::t_param2>("viziv"); auto param1 = tester.access<Params::t_param1>(); // auto param2 = tester.access<Params::t_param2>(); cout << "Access: param1 = " << param1 << endl; // cout << "Access: param2 = " << param2 << endl; return 0; }
当我使用Apple LLVM版本7.0.2(clang-700.1.81)编译此代码时,我得到以下编译错误
junk1.cpp:78:9: error: out-of-line deFinition of 'access' does not match any declaration in 'Tester' Tester::access() ^~~~~~ 1 error generated.
奇怪的是,当我取消注释代码以分配和访问param2(在上面的代码中注释掉)时,它编译得很好并产生所需的结果.
我究竟做错了什么?任何人都可以向我解释为什么包含param2会改变编译行为吗?
第一个原因是使用尾随返回类型实质上创建了模板化函数.当您尝试使用类的函数时,类类型不能是不完整的.
这就是为什么将公共访问方法的函数定义移动到类声明中的原因(Demo);只要尚未定义公共访问方法,该类就不完整,并且在该类完成之前无法定义该方法.
注意,解决此问题的另一种方法是,如果私有版本的访问以某种方式是非成员函数(例如,周围范围中的自由浮动函数).
这种方法的问题(问题的一半,因为你实际上并没有尝试这样做)是,尝试调用现在免费的浮动版访问需要编译器评估所有可能的重载,包括公共模板化访问(感谢ADL).当发生这种情况时,在non-deduced context中评估SELEct< t_detail> :: choice,并且无法获得实际的基础类型.
因此,如果我们都将Tester之外的私有访问权移动并重命名为(类似于access2),那么我们可以将声明与公共访问功能的定义分开(Demo)
以上是大佬教程为你收集整理的c – 尾随返回类型和标记分派全部内容,希望文章能够帮你解决c – 尾随返回类型和标记分派所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。