C++ 如何避免重复的模板专门化?
我有一些用于C库定义的类型的函数 这些类型是float_2、float_3、float_4、int32_2、int32_3、int32_4 这些类型有一些共同点,一个名为size的字段。 对于浮点数_2,大小=2。浮子3,尺寸=3等 现在我为每一种类型都有一个模板专门化C++ 如何避免重复的模板专门化?,c++,C++,我有一些用于C库定义的类型的函数 这些类型是float_2、float_3、float_4、int32_2、int32_3、int32_4 这些类型有一些共同点,一个名为size的字段。 对于浮点数_2,大小=2。浮子3,尺寸=3等 现在我为每一种类型都有一个模板专门化 static void add_number(rapidjson::Value &target, const char* name, float_2 src, Document::AllocatorType& a
static void add_number(rapidjson::Value &target, const char* name, float_2 src, Document::AllocatorType& alloc)
{
std::ostringstream ss;
ss << src.x << " " << src.y;
std::string s(ss.str());
target.AddMember(StringRef(name), s, alloc);
}
static void add_number(rapidjson::Value &target, const char* name, float_3 src, Document::AllocatorType& alloc)
{
std::ostringstream ss;
ss << src.x << " " << src.y << " " << src.z;
std::string s(ss.str());
target.AddMember(StringRef(name), s, alloc);
}
static void add_number(rapidjson::Value&target,const char*name,float_2 src,Document::AllocatorType&alloc)
{
std::ostringstream ss;
ss我不确定这是否与打印本身、大小或任何其他专业化要求有关。但是,我认为对于所呈现的案例,专业化程度最低的是为不同的案例重载流式处理操作符。这看起来像这样:
std::ostream& operator<<(std::ostream &stream, const float_2 &vec)
{
return stream << vec.x << ", " << vec.y;
}
std::ostream& operator<<(std::ostream &stream, const float_3 &vec)
{
return stream << vec.x << ", " << vec.y << ", " << vec.z;
}
std::ostream& operator<<(std::ostream &stream, const float_4 &vec)
{
return stream << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w;
}
template < typename T >
static void add_number(rapidjson::Value &target, const char* name, const T &src, Document::AllocatorType& alloc)
{
std::ostringstream ss;
ss << src;
std::string s(ss.str());
target.AddMember(StringRef(name), s, alloc);
}
std::ostream&operator您确实可以使用“模板魔法”(template magic)来(从)重载(集合中删除函数模板)。如果没有超过十种不同的类型,我宁愿选择运算符,因为每个float\uu
都有一个相同的参数(size
),但与x
、y
和z
不同?在这里,您无法避免专门化。某些地方必须专门化。您可以将专门化卸载到帮助器类,留下add_number()使该AddMember()成为用Help类将<代码> SRC < /C> >转换为<代码> STD::String ,但这是关于它的。C++编译器不具有人工智能作为核心语言的一部分;因此,必须编写代码来完成需要做的每一件事,一步一步,以专门的类的形式,或其他什么。else.Correct.大小字段在所有这些类型上都很常见,除了T是浮点型之外。@SamVarshavchik-我认为模板元编程可能会有一些功能,如果我理解它允许您在编译过程中执行代码,但我不太明白如何使用它,或者它是否适用于此实例。您可以重载oper非常感谢!我最终选择了流重载版本。我认为它稍微短一点。
std::ostream& operator<<(std::ostream &stream, const float_2 &vec)
{
return stream << vec.x << ", " << vec.y;
}
std::ostream& operator<<(std::ostream &stream, const float_3 &vec)
{
return stream << vec.x << ", " << vec.y << ", " << vec.z;
}
std::ostream& operator<<(std::ostream &stream, const float_4 &vec)
{
return stream << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w;
}
template < typename T >
static void add_number(rapidjson::Value &target, const char* name, const T &src, Document::AllocatorType& alloc)
{
std::ostringstream ss;
ss << src;
std::string s(ss.str());
target.AddMember(StringRef(name), s, alloc);
}
namespace detail
{
template <class T, class = int> struct has_z : std::false_type { };
template <class T> struct has_z <T, decltype((void)T::z, 0)> : std::true_type { };
template <typename T>
static auto foo_impl(T src)
-> std::enable_if_t<!has_z<T>::value>
{
std::cout << "1: " << src.x << " " << src.y << "\n";
}
template <typename T>
static auto foo_impl(T src)
-> std::enable_if_t<has_z<T>::value>
{
std::cout << "2: " << src.x << " " << src.y << " " << src.z << "\n";
}
}
template<class T>
void foo(T src)
{
detail::foo_impl(src);
}
struct A { double x{ 1 }, y{ 2 }; };
struct B { double x{ 3 }, y{ 4 }, z{ 5 }; };
int main() {
A a;
B b;
foo(a);
foo(b);
return 0;
}
1 2
3 4 5