C++ 将非模板成员函数调用转发到模板函数

标签 c++ function templates c++11 tuples

我想在我的类“Record”中隐藏一个 std::tuple 并在其上提供一个 operator[] 来访问元组的元素。不编译的天真代码是这样的:

#include <tuple>

template <typename... Fields>
class Record {
  private:
    std::tuple<Fields...> list;

  public:
    Record() {}

    auto operator[](std::size_t n)
            -> decltype(std::get<1u>(list)) {
        return std::get<n>(list);
    }
};

int main() {
    Record<int, double> r;
    r[0];
    return 0;
}

g++ 4.6 说:

x.cc:13:32: error: no matching function for call to ‘get(std::tuple<int, double>&)’
x.cc:13:32: note: candidates are:
/usr/include/c++/4.6/utility:133:5: note: template<unsigned int _Int, class _Tp1, class _Tp2> typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)
/usr/include/c++/4.6/utility:138:5: note: template<unsigned int _Int, class _Tp1, class _Tp2> const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)
/usr/include/c++/4.6/tuple:531:5: note: template<unsigned int __i, class ... _Elements> typename std::__add_ref<typename std::tuple_element<__i, std::tuple<_Elements ...> >::type>::type std::get(std::tuple<_Elements ...>&)
/usr/include/c++/4.6/tuple:538:5: note: template<unsigned int __i, class ... _Elements> typename std::__add_c_ref<typename std::tuple_element<__i, std::tuple<_Elements ...> >::type>::type std::get(const std::tuple<_Elements ...>&)

基本上我想调用 Record::operator[] 就像在数组上一样。这可能吗?

最佳答案

get 的参数是一个编译时常量。你不能使用 为此的运行时变量,你不能有一个单一的功能 返回 tuple 成员,因为您的返回类型将是 错误的。你可以做的是滥用非类型参数推导:

#include <tuple>

template<typename... Args>
struct Foo {
  std::tuple<Args...> t;

  template<typename T, std::size_t i>
  auto operator[](T (&)[i]) -> decltype(std::get<i>(t)) {
    return std::get<i>(t);
  }
  // also a const version
};

int main()
{
  Foo<int, double> f;
  int b[1];
  f[b];
  return 0;
}

这太可怕了,我永远不会使用它,它对用户来说也没有多大意义。我只是通过模板成员转发 get

我将尝试解释为什么我认为这真的很邪恶:函数的返回类型仅取决于编译时事实(这对于 virtual 成员函数略有变化)。让我们假设在某些情况下可以进行非类型参数推导(函数调用参数是 constexpr),或者我们可以构建一些可以很好地隐藏它的东西,您的用户不会意识到他们的返回类型刚刚改变,隐式转换会对它们造成讨厌的事情。明确这一点可以避免一些麻烦。

关于C++ 将非模板成员函数调用转发到模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9150198/

相关文章:

C++:使用 std::unique_ptr 访问重载 operator++ 的最佳方式?

c++ - LNK2019未解析的外部符号。创建二叉树

c - 需要创建一个函数来编码一个单词

javascript - 创建带有函数参数的变量

C++:未使用嵌入式模板调用析构函数

c++ - 编译器推断模板参数

c++ - C++中的 vector 运算

c++ - 带按值参数 & noexcept 的构造函数

R:为多个不同变化的参数评估函数

c++ - 指针和整数模板的内存泄漏。我究竟做错了什么?