C++:如何使用模板函数中的类型进行分支?

Ash*_*ppa 9 c++ template-function

我对模板不太熟悉.如何编写一个名为get的模板函数,根据模板类型选择从中获取的数组?请参阅以下示例:

struct Foo
{
    int iArr[10];
    char cArr[10];

    // How to pick array here based on template type?
    template < typename T >
    T get( int idx )
    {
        // This does NOT work!
        switch ( T )
        {
        case int:
            return iArr[ idx ];
        case char:
            return cArr[ idx ];
        }
    }
};

// Expected behaviour of get()
Foo foo;
int i  = foo.get< int >( 2 );
char c = foo.get< char >( 4 );
Run Code Online (Sandbox Code Playgroud)

ild*_*arn 9

虽然Jason提出的解决方案有效,但它远非惯用,并且更难维护,因为声明中的caseswitch1)没有明显的意义("幻数")和2)很容易与其中的值不同步switch_value<>专业化.我建议这样做:

struct Foo {
    Foo() : iArr(), cArr() { }

    template<typename T>
    T get(std::size_t const idx) const     {
        return Foo::get_dispatcher<T>::impl(*this, idx);
    }

private:
    int iArr[10];
    char cArr[10];

    template<typename T>
    struct get_dispatcher;
};

template<>
struct Foo::get_dispatcher<int> {
    static int impl(Foo const& foo, std::size_t const idx) {
        return foo.iArr[idx];
    }
};

template<>
struct Foo::get_dispatcher<char> {
    static char impl(Foo const& foo, std::size_t const idx) {
        return foo.cArr[idx];
    }
};
Run Code Online (Sandbox Code Playgroud)

Foo::get<>使用除intor 之外的任何类型调用或char将产生编译器错误.


Jas*_*son 8

您需要添加某种类型的值结构,您可以使用它来获取switch-statement的值.例如:

template<typename T>
struct switch_value {};

template<>
struct switch_value<int>
{
    enum { value = 1 };
};

template<>
struct switch_value<char>
{
    enum { value = 2 };
};

//then inside you structure Foo
template <typename T>
T get( int idx )
{
    switch ( switch_value<T>::value )
    {
    case 1:
        return iArr[ idx ];
    case 2:
        return cArr[ idx ];
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的好处是如果你使用一个没有有效值的类型会抛出一个编译器错误,因为默认版本switch_value<T>没有定义一个成员value,所以如果你没有专门针对特定类型的结构,那么模板实例化将失败.