Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何避免重复的模板专门化?_C++ - Fatal编程技术网

C++ 如何避免重复的模板专门化?

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

我有一些用于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& 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