在编写特征以进行参考和非参考类型时,如何减少重复

How to reduce duplication when writing traits for reference and non reference types when the traits are the same

本文关键字:参考 类型 何减少 特征      更新时间:2023-10-16

我有例如

#include <iostream>
template <typename T>
struct Base {};
template <>
struct Base<std::string> {
  static const int value = true;
};
template <>
struct Base<std::string &> {
  static const int value = true;
};
int main() {
  bool a = Base<std::string>::value;
  bool b = Base<std::string &>::value;
  std::cout << a << b << std::endl;
}

https://godbolt.org/z/0npyxb

注意,我有两个相同的专业,并希望将其简化为一个。我知道有两种解决方案我不想做。

(1(在呼叫站点上删除参考,以便仅需要一个专业化。

(2(创建一个基类并继承参考 no thit。

是否有第三个选项,其中专业化是普通的,而不是参考类型?

C 11解决方案。

1(似乎很好:

template <typename T>
struct BaseImpl {};
template <>
struct BaseImpl<std::string> {
  static const int value = true;
};
template <typename T>
using Base = BaseImpl<typename std::remove_reference<T>::type>;

2(似乎有更多的详细信息

template <typename T>
struct BaseImpl {};
template <>
struct BaseImpl<std::string> {
  static const int value = true;
};
template <typename T>
struct Base : BaseImpl<T> {}; // or directly BaseImpl<std::remove_reference_t<T>>
template <typename T>
struct Base<T&> : BaseImpl<T> {};

3(类似于2(,更少的冗长,但可能更棘手

template <typename T>
struct Base : Base<T&> {};
template <typename T>
struct Base<T&> {};
template <>
struct Base : Base<std::string> {
    static const int value = true;
};

1(似乎更易读,易于实现。

您可以在Sfinae上下文中执行检查:

// type trait to remove the lvalue-reference
template< class T > struct remove_lvalue_reference      {typedef T type;};
template< class T > struct remove_lvalue_reference<T&>  {typedef T type;};
template <typename T>
using remove_lvalue_reference_t = typename remove_lvalue_reference<T>::type;
template <typename T, typename = void>
struct Base {};
// valid when T is std::string and std::string&
template <typename T>
struct Base<T, typename std::enable_if<std::is_same<std::string, remove_lvalue_reference_t<T>>::value>::type> {
  static const int value = true;
};

live

enable_if有点沉重,但我认为没有更好的方法。

#include <iostream>
#include <type_traits>
template <typename T, typename Enable = void>
struct Base {};

template <typename T>
struct Base<
    T,
    typename std::enable_if< 
       std::is_same<typename std::decay<T>::type, std::string>::value
    >::type 
>
{
  static const int value = true;
};
int main() {
  bool a = Base<std::string>::value;
  bool b = Base<std::string &>::value;
  std::cout << a << b << std::endl;
}

https://godbolt.org/z/98vzfn