c++ 使用模板化类型内定义的类型

ui7jx7zq  于 2023-01-03  发布在  其他
关注(0)|答案(2)|浏览(119)

有什么好办法可以做到以下几点吗?

/* vvv */
template<typename Wrapper> using T = typename Wrapper::type
T f(const T &a, const T &b) { 
    return a + b; 
}

其中Wrapper是包含在其内部定义的(若干)类型的某个类。
我可以这样做,但我不喜欢这种方法,因为它使函数有几个模板类型(也没有完全相同的含义):

template<typename Wrapper, typename T = typename Wrapper::type>
T f(..)

我这样做纯粹是为了减少在函数声明中输入typename Wrapper::type的样板。如果有更好的方法,请告诉我。

  • 注意:* 在我的项目中,Wrapper类型需要满足某些概念,这也需要在Wrapper类型中定义type类型。

如果有帮助的话,下面是我的用例。我正在(尝试)编写一个线性代数库。在这个场景中,为了创建向量或矩阵之类的对象,我们需要提供一个字段F,它必须满足:

  • F在某个基本类型T上(例如F::type
  • F提供了两个操作OpAddOpMul,这两个操作都可以在T上操作。

使用概念来定义它很简单,但是这会增加一些混乱,比如我上面的例子。

h43kikqp

h43kikqp1#

你知道类型是什么吗?如果知道,你可以提供模板参数:

template<class T>
using inner = typename T::type;

template<class T>
inner<T> f(inner<T> const& a, inner<T> const& b);

// ...
f<X>(y, y);
slhcrj9b

slhcrj9b2#

在特殊情况下,你不喜欢的是唯一的解决办法

#include <type_traits>

template<typename Wrapper,
         typename T = typename Wrapper::type,
         typename std::enable_if<std::is_same<T, typename Wrapper::type>::value>::type* = nullptr>
T f(const T &a, const T &b) { 
    return a + b; 
}

struct S {
  typedef long type;
};

int main() {
  f<S>(0L, 0L);   // ok
  // f<S>(0, 0);  // failure

  // If the second type is set explicitly 
  f<S, long>(0L, 0L);    // ok
  f<S, long>(0, 0);      // ok
  // f<S, int>(0L, 0L);  // failure
  // f<S, int>(0, 0);    // failure
}

这是一个比inner<T>更好的解决方案,因为f<S>(0, 0)不会因inner<T>而失败-需要确切的long,但int通过。

相关问题