C++ 可变模板参数方法的部分特化
我有一个成功编译的代码(g++4.9.2):C++ 可变模板参数方法的部分特化,c++,c++11,c++14,C++,C++11,C++14,我有一个成功编译的代码(g++4.9.2): #包括 #包括 //任意可变模板参数的一般函数 模板 无效的 foo(T&arg) { std::cout xxx xxx=>xxx xxx=>xxx std::pair=>T 现在我想将这些foo方法放在一个类中,并编写: #include <iostream> #include <utility> class abc { public: // general function for any variadic
#包括
#包括
//任意可变模板参数的一般函数
模板
无效的
foo(T&arg)
{
std::cout xxx
xxx=>xxx
xxx=>xxx
std::pair=>T
现在我想将这些foo方法放在一个类中,并编写:
#include <iostream>
#include <utility>
class abc
{
public:
// general function for any variadic templated argument
template<template<typename ...> class T, typename ...TTs>
void
foo(T<TTs...>& arg)
{
std::cout << "T<TTs...>" << std::endl;
}
};
template<typename ...Ts>
struct xxx
{
// not important
};
// specialization for only variadic templated xxx
template<typename ...TTs> void
abc::foo(xxx<TTs...>& arg)
{
std::cout << "xxx<TTs...>" << std::endl;
}
// specialization for non-variadic templated xxx
template<typename TT> void
abc::foo(xxx<TT>& arg)
{
std::cout << "xxx<TT>" << std::endl;
}
// specialization for xxx<uint8_t>
template<> void
abc::foo(xxx<uint8_t>& arg)
{
std::cout << "xxx<uint8_t>" << std::endl;
}
int
main(int argc, char** argv)
{
abc p;
xxx<uint8_t> x1;
std::cout << "xxx<uint8_t> => ";
p.foo(x1);
xxx<uint16_t> x2;
std::cout << "xxx<uint16_t> => ";
p.foo(x2);
xxx<uint8_t,uint16_t> x3;
std::cout << "xxx<uint8_t,uint16_t> => ";
p.foo(x3);
std::pair<uint8_t,uint16_t> x4;
std::cout << "std::pair<uint8_t,uint16_t> => ";
p.foo(x4);
return 0;
}
#包括
#包括
abc班
{
公众:
//任意可变模板参数的一般函数
模板
无效的
foo(T&arg)
{
标准::cout
这不是专门化。这是另一个模板函数,其名称foo
与上述模板函数重载
// specialization for xxx<uint8_t>
template<> void
foo(xxx<uint8_t>& arg)
{
std::cout << "xxx<uint8_t>" << std::endl;
}
这又是一个全新的重载foo
。重载远没有全功能专门化那么古怪
没有部分模板函数专门化这样的事情
这就解释了为什么用相同语法专门化方法的尝试不起作用。也没有部分模板成员函数专门化
您要么在类本身中编写重载,要么将其分派到不同的上下文
“出错”和导致错误的直接原因是您的初始代码引入了新的重载。不允许您在类定义之外引入方法的新重载,因此编译器指出了您的错误
下面是一个有用的技巧。我们在abc
// general function for any variadic templated argument
template<template<typename ...> class T, typename ...TTs>
void foo(T<TTs...>& arg)
{
return foo(*this, arg);
}
private:
template<template<typename ...> class T, typename ...TTs>
friend void foo(abc& self, T<TTs...>& arg)
{
std::cout << "T<TTs...>" << std::endl;
}
template<typename ...TTs> void
foo(abc& self, xxx<TTs...>& arg)
{
std::cout << "xxx<TTs...>" << std::endl;
}
template<typename TT> void
foo(abc& self, xxx<TT>& arg)
{
std::cout << "xxx<TT>" << std::endl;
}
inline void foo(abc& self, xxx<uint8_t>& arg)
{
std::cout << "xxx<uint8_t>" << std::endl;
}
当调用abc::foo
时,可以通过ADL找到它们。不可能部分专门化函数模板。没有这样的事情。你可以重载函数模板,并完全专门化它,但如果你认为你是部分专门化的,那你就错了。一般来说,如果你摆脱了完全专门化,你会身体好一点。
// general function for any variadic templated argument
template<template<typename ...> class T, typename ...TTs>
void
foo(T<TTs...>& arg)
{
std::cout << "T<TTs...>" << std::endl;
}
template<typename ...Ts>
struct xxx
{
// not important
};
// specialization for only variadic templated xxx
template<typename ...TTs> void
foo(xxx<TTs...>& arg)
{
std::cout << "xxx<TTs...>" << std::endl;
}
// specialization for non-variadic templated xxx
template<typename TT> void
foo(xxx<TT>& arg)
{
std::cout << "xxx<TT>" << std::endl;
}
// specialization for xxx<uint8_t>
template<> void
foo(xxx<uint8_t>& arg)
{
std::cout << "xxx<uint8_t>" << std::endl;
}
inline foo(xxx<uint8_t>& arg)
{
std::cout << "xxx<uint8_t>" << std::endl;
}
// general function for any variadic templated argument
template<template<typename ...> class T, typename ...TTs>
void foo(T<TTs...>& arg)
{
return foo(*this, arg);
}
private:
template<template<typename ...> class T, typename ...TTs>
friend void foo(abc& self, T<TTs...>& arg)
{
std::cout << "T<TTs...>" << std::endl;
}
template<typename ...TTs> void
foo(abc& self, xxx<TTs...>& arg)
{
std::cout << "xxx<TTs...>" << std::endl;
}
template<typename TT> void
foo(abc& self, xxx<TT>& arg)
{
std::cout << "xxx<TT>" << std::endl;
}
inline void foo(abc& self, xxx<uint8_t>& arg)
{
std::cout << "xxx<uint8_t>" << std::endl;
}