如果类型的大小大于 X,如何实现接受类型并计算引用的类型特征?

How do you implement a type trait that takes a type and evaluates a reference if the size of the type is greater than X?

我一直在实现几个数据结构 类,它们应该能够容纳任何类型,最近我 'upgrading' 它们具有类型特征。

我想实现一种类型特征,以防止将非常大的值用作硬拷贝。例如:

template<typename T>
T Max(T a, T b){ return (a < b) ? b : a; }

如果 T 碰巧有一个离谱的大小,我不想将 T 作为一个值。

相反,我想要这样的东西:

template<typename T>
 T Max(ref_if_large<T>::val a, ref_if_large<T>::val b){ return (a < b) ? b : a; }

我尝试自己实施这个,但我已经陷入其中一个我只是看不出有什么问题的时刻。

template<typename T, bool cond>
struct ref_if_true {
    using V = T;
};

template<typename T>
struct ref_if_true<T, true> {
    using V = T&;
};

template<typename T>
struct ref_if_large {
    using val = 
        ref_if_true< T, ((sizeof(T)) > (12U))>::V;
};

编译器抱怨 V 没有被定义,但老实说我不明白为什么。

你需要加上typename来告诉编译器V确实是一个类型

template<typename T>
struct ref_if_large {
    using val = 
        typename ref_if_true< T, ((sizeof(T)) > (12U))>::V;
};

顺便说一下,考虑对大型类型使用 const 引用。它们将允许绑定到 const 对象和右值。

您还可以使用别名模板来避免在客户端代码中散布 typenames:

template<typename T>
using ref_if_large = typename ref_if_true<T, ((sizeof(T)) > (12U))>::V;

如果你是引用,你也可以参数化 return 类型。

template<typename T>
ref_if_large<T> Max(ref_if_large<T> a, ref_if_large<T> b){
    return (a < b) ? b : a;
}

在最后一个定义中,为依赖类型添加 typename,如下所示:using val = typename ref_if_true<blah>::V;。但是说真的,不要对 max 函数这样做。别名问题已经够多了,不要再不确定是否会出现别名了。


Boost 库的 boost::call_traits<T>::param_type 已经做到了“最佳参数类型”。

如果想避免对 Boost 的依赖,那么再次发明它当然是有意义的(我自己做过)。

但是,至少了解 Boost 功能很有用。

这里的其他两个答案已经充分回答了具体问题。值得额外指出的是 ref_if_true 是标准库中已经存在的类型特征的特定版本:std::conditional:

template <class T, bool cond>
using ref_if_true_t = std::conditional_t<cond, T&, T>;

因此,不需要以以下内容开头:

template<typename T>
using ref_if_large_t = std::conditional_t<(sizeof(T) > 12U), T&, T>;

或者真的很可能:

template<typename T>
using ref_if_large_t = std::conditional_t<(sizeof(T) > 12U), T const&, T>;

因为提到非 const 意味着不同的东西。


注意:元编程已经很难了。如果你用自己的命名约定开辟自己的道路,那就更难了。产生类型的元函数应将其命名为 type(而不是 Vval)。