我正在将具有一组专门用于类内枚举器值的模板成员函数的现有类转换为模板类。但是,语言不允许在没有类模板专门化的情况下对模板成员函数进行专门化,因此这不起作用:
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;
}
所以我想我可以通过把模板函数体放在内部模板类的类内部分专门化的静态函数的内部来解决这个问题。然而,这种方法也不起作用:
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;
}
clang gives
:
prog.cc:30:9: error: no candidate function template was found for dependent friend function template specialization
doo<t_KindId::first>(void) -> void;
^
prog.cc:52:26: error: incomplete definition of type 't_Test<int>::t_DooImpl<t_Test<int>::t_KindId::first, void>'
return t_DooImpl<x_kind>::doo_impl(*this);
~~~~~~~~~~~~~~~~~^~
prog.cc:59:4: note: in instantiation of function template specialization 't_Test<int>::doo<t_Test<int>::t_KindId::first>' requested here
t.doo<t_Test::t_KindId::first>();
^
2 errors generated.
gcc gives
:
prog.cc: In instantiation of 'class t_Test<int>::t_DooImpl<(t_Test<int>::t_KindId)0, void>':
prog.cc:52:36: required from 'void t_Test<x_Dummy>::doo() [with t_Test<x_Dummy>::t_KindId x_kind = (t_Test<int>::t_KindId)0; x_Dummy = int]'
prog.cc:59:33: required from here
prog.cc:29:15: error: 'doo' was not declared in this scope
friend auto t_Test<x_Dummy>::
^~~~~~~~~~~~~~~
prog.cc:29:15: note: suggested alternative: 'bool'
friend auto t_Test<x_Dummy>::
^~~~~~~~~~~~~~~
bool
prog.cc: In instantiation of 'void t_Test<x_Dummy>::doo() [with t_Test<x_Dummy>::t_KindId x_kind = (t_Test<int>::t_KindId)0; x_Dummy = int]':
prog.cc:59:33: required from here
prog.cc:52:36: error: 'static void t_Test<x_Dummy>::t_DooImpl<t_Test<x_Dummy>::t_KindId::first, xx_Dummy>::doo_impl(t_Test<x_Dummy>&) [with xx_Dummy = void; x_Dummy = int]' is private within this context
return t_DooImpl<x_kind>::doo_impl(*this);
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
prog.cc:33:3: note: declared private here
doo_impl
^~~~~~~~
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
我不确定这里的语法,但似乎问题是由friend声明引起的。如果我做
doo_impl
功能公开和删除
friend
声明它与clang和gcc编译得很好,但vc仍然抱怨。所以我想找一些建议来解决这个问题,或者找一个更简单的解决方法。