0

我正在开发一个围绕 C api 的 C++11 包装器。C api 为各种类型提供了一堆 getter,每种类型都有不同的名称。值由给定大小的数组检索,在编译时已知。

我想通过模板给出类型和数组大小,以调用正确的函数。

#include <string>
#include <iostream>

template <typename T>
struct make_stop {
    constexpr static bool value = false;
};

class Foo
{
public:
    Foo() : i(42) {}

    template<typename T, size_t n>
    T get();

private:
    int i = 0;
};

template<typename T, size_t n>
T Foo::get() { static_assert(make_stop<T>::value); return T(); }

template<int, size_t n>
int Foo::get() { return i + n; }

int main() {
    Foo foo;

    int i = foo.get<int, 4>();
    double f = foo.get<double, 2>();


    return 0;
}

但它无法匹配正确的功能

main.cpp:26:5: error: no declaration matches 'int Foo::get()'

 int Foo::get() { return i + n; }
     ^~~

main.cpp:15:7: note: candidate is: 'template<class T, long unsigned int n> T Foo::get()'

     T get();
4

2 回答 2

1

从你的问题来看它有点模糊,但假设你想要索引到一些 c-arrays 并返回I你不能像你想要的那样专门化函数模板的值,但是你可以使用一些标签来代替,比如..

class Foo
{
public:
    Foo() : is{1,2,3,4,5,6,7,8,9,10},ds{1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.1} {}


    template <typename T> struct type_c{};
    template <size_t I> struct int_c{};

    template<typename T,size_t I>
    auto get() 
    { return get_impl(type_c<T>(),int_c<I>()); }

private:

    template <size_t I>
    auto get_impl(type_c<int>,int_c<I>) 
    { return is[I]; }

    template <size_t I>
    auto get_impl(type_c<double>,int_c<I>) 
    { return ds[I]; }


    int is[10];
    double ds[10];
};
int main() {
    Foo foo;

    int i = foo.get<int,0>();
    double d = foo.get<double,2>();
    std::cout << i << " " << d << std::endl;
    return 0;
}

演示

于 2018-06-22T01:08:57.820 回答
0

如果我对您的理解正确,您想partially专攻T. 不幸的是,标准不允许方法的部分专业化。但是,您可以使用由该类模板化T并专门化该类的类上的静态方法来解决此问题。

像这样:

template <class T> struct Foo_helper;

struct Foo
{
    Foo() : i{42} {}

    template<class T, std::size_t N>
    T get()
    {
        return Foo_helper<T>::template get<N>(*this);
    }

    int i = 0;
};

template <class T> struct Foo_helper {};
// specialize Foo_helper for each type T you wish to support:

template <> struct Foo_helper<int>
{
    template <std::size_t N>
    static int get(const Foo& foo) { return foo.i + N; }
};
template <> struct Foo_helper<double>
{
    template <std::size_t N>
    static double get(const Foo& foo) { return foo.i + N; }
};


int main()
{
    Foo foo{};

    int i = foo.get<int, 4>();
    double d = foo.get<double, 2>();
}
于 2018-06-22T00:45:35.800 回答