【问题标题】:partially specialize function template with no parameters不带参数的部分特化函数模板
【发布时间】:2016-03-24 20:43:11
【问题描述】:

我认为这是不可能的,但一定有人知道得更好......

template<typename T>   
T Read()   //T is int, char, etc
{
    return read<T>();
}

template<typename T, Size> 
std::array<T,Size> Read<std::array<T, Size>>()
{
     return unique_read<T, Size>();
}

我猜只要我指定任何模板参数,它就不再是完全特化,函数中也不允许部分特化

我唯一能想到的是:

template<typename T>
struct _dummy
{
    T Read() {
        return T();
    };
};

template<typename T, size_t Size>
struct _dummy<std::array<T, Size>>
{
    using ArrayType = std::array<T, Size>;

    ArrayType Read() {
        return ArrayType();
    };
};

【问题讨论】:

  • 你想做什么?现在你只是在展示复杂的写作方式T{}
  • @Barry 我想以一种方式处理所有 T,除了 std:.arrays。这就是我想要做的。
  • 你可能想让你的Read_dummy 中是静态的,但除此之外,这是偏函数特化的一个技巧。
  • @SergeyA read 函数在一个类中,所以我想我必须修改 read 以在每次调用时获取指向外部类的指针并将其设为静态,或者创建一个 _dummy 对象在我的班级中,并且只将指针传递给外部班级一次。我想避免这两件事:

标签: c++ templates c++14 template-specialization


【解决方案1】:

你应该为这种工作使用标签调度:

namespace detail {
template<class T>struct tag{};

template<class T>
T Read(tag<T>) {
    return T{};
}

template<class T, std::size_t N>
std::array<T, N> Read(tag<std::array<T, N>>) {
    return {1,2,3};
}
}

template<class T>
auto Read() {
    return detail::Read(detail::tag<T>());
}

int main() {
    Read<std::array<int,5>>();
}

【讨论】:

  • 谢谢,我想我会去那个。我猜由于参数未命名,编译器应该足够聪明,可以内联所有内容,并且不传递任何参数。
  • @Phantom 不是因为它未命名,不是。因为它有微不足道的特殊成员函数,没有副作用。
  • @Phantom,如果您不想受制于优化器,您可以随时将函数参数替换为模板参数,而根本不创建任何对象。
  • @SergeyA:但是,我们处于与 start 相同的状态:我们不能部分专门化模板函数。
  • @Jarod42,不知道我在想什么。你是对的,当然。
【解决方案2】:

另一种方法是遵循函数对象:

template<class T> 
struct reader_op {
  T operator()() const { 
    // whatever needs to happen here
  }
};

// partially specialise for array case
template<class T, size_t N> 
struct reader_op<std::array<T, N>> {
  std::array<T, N> operator()() const { 
    // whatever needs to happen here
  }
};

// reader_op class type is now deduced from T
// when T is a std::array, our specialised function object will
// be used
template<typename T>   
T Read()   //T is int, char, etc
{
    return reader_op<T>()();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多