c++ - 使用非专用模板化类型作为模板参数

标签 c++ c++11 templates dynamic refactoring

<分区>

这是我想要实现的运行示例:

#include <iostream>
#include <string>
#include <typeinfo>

template <class T> 
struct print
{
    static void function( T thing)
    {
        std::cout << thing << std::endl;
    }
};

template <class T>
struct printMore
{
    static void function( T thing )
    {
        std::cout << thing << " and more" << std::endl;
    }
};

struct dynamicBase
{
    const char* m_value;

    size_t getType()
    {
        switch( *m_value )
        {
        case '0': //the string is going to be a small script, the type returned is known during execution but not at compile time
            return typeid( int ).hash_code();
        case '1':
            return typeid( float ).hash_code();
        }
        return typeid( const char* ).hash_code();
    }

    template<class T>
    T* tryGetValue()
    {
        if( getType() == typeid( T ).hash_code() )
            return (T*) ( &( m_value[1] ) ); //dumb example, actually I'll evaluate the string as script and return a value based on that
        else
            return nullptr;
    }

    void applyPrint(  )
    {
        if( int* t = tryGetValue<int>() )
            print<int>::function( *t ); //I can cout an int so this line compile
        else if( float* t = tryGetValue<float>() )
            print<float>::function( *t ); //I can cout a float so this one too
        else
            print<const char*>::function( *tryGetValue<const char*>() ); //same
    }
    void applyPrintMore()
    {
        if( int* t = tryGetValue<int>() )
            printMore<int>::function( *t ); 
        else if( float* t = tryGetValue<float>() )
            printMore<float>::function( *t );
        else
            printMore<const char*>::function( *tryGetValue<const char*>() ); //same
    }

    //.... applyprintPretty, applyprintInRed, applyprintInBlue, .....
};

int main()
{
    dynamicBase d;
    d.m_value = "0a\0\0\0";
    d.applyPrint(); //97 == ascii value of 'a'

    __asm {nop}; //for breakpoint purpose
}

起初我以为我可以使用这样的模板:

    template<class myFunctionClass>
    void applyPrint(  )
   {
        if( int* t = tryGetValue<int>() )
            myFunctionClass<int>::function( *t ); 
        else if( float* t = tryGetValue<float>() )
            myFunctionClass<float>::function( *t ); 
        else
            myFunctionClass<const char*>::function( *tryGetValue<const char*>() ); 
    }

然后意识到我的错误(模板类型不是类型,除非你给它们模板参数)。但是有没有办法重构这段代码,这样我就没有 15 个 applyStuff 函数了? (我做错了,不是吗?)

最佳答案

您正在寻找模板模板参数:

template<template <typename> class myFunctionClass>
void applyPrint(  )
{
        if( int* t = tryGetValue<int>() )
            myFunctionClass<int>::function( *t ); 
        else if( float* t = tryGetValue<float>() )
            myFunctionClass<float>::function( *t ); 
        else
            myFunctionClass<const char*>::function( *tryGetValue<const char*>() ); 
}

您可以找到一个引用 here: "cppreference.com - Template template parameters" .

关于c++ - 使用非专用模板化类型作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42817827/

相关文章:

c++ - 隐藏类(class)私有(private)成员的最佳方式

c++ - 类与 vector 的 unique_ptr 到类

c++ - 相互递归 lambda

c++ - 显式指定通用 lambda 的 operator() 模板参数是否合法?

c# - kendo 网格控件中的 DropDownList(通过 ClientTemplate)

c++ - "vector subscript out of range"

c++ - 对如何初始化类成员感到困惑

c++ - 如何在没有无限循环的情况下使用 CMake 的 add_subdirectory

c++11 - C++ 迭代器不匹配错误

javascript - 如何编写 JavaScript 模板类?