C++ 当模板类未专门化时,为模板类的模板成员函数编写专门化的变通方法
我正在将具有一组专门用于类内枚举器值的模板成员函数的现有类转换为模板类。但是,语言不允许在没有类模板专门化的情况下专门化模板成员函数,因此这不起作用:C++ 当模板类未专门化时,为模板类的模板成员函数编写专门化的变通方法,c++,templates,c++17,specialization,C++,Templates,C++17,Specialization,我正在将具有一组专门用于类内枚举器值的模板成员函数的现有类转换为模板类。但是,语言不允许在没有类模板专门化的情况下专门化模板成员函数,因此这不起作用: template <typename x_Dummy> class t_Test { public: enum t_KindId{first, second}; public: template <t_KindId x_kind> auto doo() -> void; }; template &
template <typename x_Dummy>
class t_Test
{
public:
enum t_KindId{first, second};
public:
template <t_KindId x_kind> auto doo() -> void;
};
template <typename x_Dummy>
template<>
inline auto t_Test<x_Dummy>::doo<t_Test<x_Dummy>::t_KindId::first>() -> void
{
return;
}
模板
类t_检验
{
公众:
枚举t_KindId{first,second};
公众:
模板自动doo()->void;
};
模板
模板
内联自动测试::doo()->void
{
返回;
}
所以我发现我可以通过将模板函数体放在内部模板类的类内部分专门化的静态函数中来解决这个问题。但是,这种方法也不起作用:
template <typename x_Dummy>
class t_Test
{
public:
enum class t_KindId{first, second};
public:
template <t_KindId x_kind> auto doo() -> void;
private:
template <t_KindId x_kind, typename xx_Dummy = void>
class t_DooImpl;
private:
template <typename xx_Dummy>
class t_DooImpl<t_KindId::first, xx_Dummy> final
{
friend auto t_Test<x_Dummy>::doo<t_KindId::first>() -> void;
private:
static inline auto doo_impl([[maybe_unused]] t_Test<x_Dummy> & self) -> void
{
return;
}
};
};
template <typename x_Dummy>
template <typename t_Test<x_Dummy>::t_KindId x_kind>
inline auto t_Test<x_Dummy>::doo(void) -> void
{
return t_DooImpl<x_kind>::doo_impl(*this);
}
int main()
{
using t_Test = t_Test<int>;
t_Test t{};
t.doo<t_Test::t_KindId::first>();
return 0;
}
模板
类t_检验
{
公众:
枚举类t_KindId{first,second};
公众:
模板自动doo()->void;
私人:
模板
t_DooImpl类;
私人:
模板
课程t_DooImpl期末考试
{
朋友自动测试::doo()->void;
私人:
静态内联自动doo_impl([[可能未使用]]t_Test&self)->void
{
返回;
}
};
};
模板
模板
内联自动测试::doo(void)->void
{
返回t_DooImpl::doo_impl(*this);
}
int main()
{
使用t_检验=t_检验;
t_检验t{};
t、 doo();
返回0;
}
:
prog.cc:30:9:错误:未找到从属好友函数模板专用化的候选函数模板
doo(无效)->无效;
^
程序cc:52:26:错误:类型“t_Test::t_DooImpl”的定义不完整
返回t_DooImpl::doo_impl(*this);
~~~~~~~~~~~~~~~~~^~
prog.cc:59:4:注意:在函数模板专门化的实例化中,此处请求了't_Test::doo'
t、 doo();
^
产生2个错误。
:
prog.cc:t_Test::t_DooImpl类实例化中:
prog.cc:52:36:从“void t_Test::doo()[带t_Test::t_KindId x_kind=(t_Test::t_KindId)0;x_Dummy=int]中需要
进度cc:59:33:此处需要
prog.cc:29:15:错误:“doo”未在此范围内声明
朋友自动测试::
^~~~~~~~~~~~~~~
进度cc:29:15:注:建议的备选方案:“bool”
朋友自动测试::
^~~~~~~~~~~~~~~
布尔
prog.cc:在“void t_Test::doo()[带t_Test::t_KindId x_kind=(t_Test::t_KindId)0;x_Dummy=int]”的实例化中:
进度cc:59:33:此处需要
prog.cc:52:36:错误:“static void t_Test::t_DooImpl::doo_impl(t_Test&)[with xx_Dummy=void;x_Dummy=int]在此上下文中是私有的
返回t_DooImpl::doo_impl(*this);
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
程序cc:33:3:注:此处声明为私有
杜欧普
^~~~~~~~
vc++提供:
warning C4348: 't_Test<int>::t_DooImpl': redefinition of default parameter: parameter 2
note: see declaration of 't_Test<int>::t_DooImpl'
note: see reference to class template instantiation 't_Test<int>' being compiled
error C2027: use of undefined type 't_Test<int>::t_DooImpl<t_Test<int>::t_KindId::first,void>'
note: see declaration of 't_Test<int>::t_DooImpl<t_Test<int>::t_KindId::first,void>'
note: see reference to function template instantiation 'void t_Test<int>::doo<t_Test<int>::t_KindId::first>(void)' being compiled
note: see reference to function template instantiation 'void t_Test<int>::doo<t_Test<int>::t_KindId::first>(void)' being compiled
error C3861: 'doo_impl': identifier not found
警告C4348:'t_Test::t_DooImpl':重新定义默认参数:参数2
注:见“t_Test::t_DooImpl”的声明
注意:请参阅正在编译的类模板实例化“t_Test”
错误C2027:使用未定义的类型“t_Test::t_DooImpl”
注:见“t_Test::t_DooImpl”的声明
注意:请参阅正在编译的函数模板实例化“void t_Test::doo(void)”的参考
注意:请参阅正在编译的函数模板实例化“void t_Test::doo(void)”的参考
错误C3861:“doo_impl”:找不到标识符
我不确定这里的语法,但问题似乎是由友元声明引起的。如果我将
doo_impl
函数公开,并删除friend
声明,它可以很好地编译clang和gcc,但vc仍然抱怨。因此,我正在寻找关于如何解决这一问题的建议,或者寻找更简单的解决方法。添加一个可以专门化的层,可能会为枚举添加重载:
template <typename T>
class t_Test
{
public:
enum t_KindId {first, second};
public:
template <t_KindId x_kind> void doo() { doo_impl(std::integral_constant<t_KindId , x_kind>{}); }
private:
void doo_impl(std::integral_constant<t_KindId , first>);
void doo_impl(std::integral_constant<t_KindId , second>);
};
模板
类t_检验
{
公众:
枚举t_KindId{first,second};
公众:
模板void doo(){doo_impl(std::integral_常量{});}
私人:
void doo_impl(标准:积分常数);
void doo_impl(标准:积分常数);
};
然后:
template <typename T>
void t_Test<T>::doo_impl(std::integral_constant<typename t_Test<T>::t_KindId , t_Test<T>::first>)
{
std::cout << "first" << std::endl;
}
template <typename T>
void t_Test<T>::doo_impl(std::integral_constant<typename t_Test<T>::t_KindId , t_Test<T>::second>)
{
std::cout << "second" << std::endl;
}
模板
无效t_测试::doo_impl(标准::积分常数)
{
std::我能不能通过添加#include
并将doo\u impl
定义移动到类主体中,让vc也能使用它。
template <typename T>
class t_Test
{
public:
enum t_KindId {first, second};
public:
template <t_KindId x_kind> void doo() { doo_impl(std::integral_constant<t_KindId , x_kind>{}); }
private:
void doo_impl(std::integral_constant<t_KindId , first>);
void doo_impl(std::integral_constant<t_KindId , second>);
};
template <typename T>
void t_Test<T>::doo_impl(std::integral_constant<typename t_Test<T>::t_KindId , t_Test<T>::first>)
{
std::cout << "first" << std::endl;
}
template <typename T>
void t_Test<T>::doo_impl(std::integral_constant<typename t_Test<T>::t_KindId , t_Test<T>::second>)
{
std::cout << "second" << std::endl;
}