首页 > 解决方案 > 基于模板参数的模板实例化发出警告

问题描述

如果我们的头文件的用户使用某些模板化类型实例化模板,我们想要发出编译器警告,到目前为止我们通过模板专业化做到了这一点:

#include <deque>
#include <vector>

template <typename T, template <typename...> class CONTAINER>
struct select_container {
  using _t =
      CONTAINER<T>;  // we don't have custom allocators for most containers
};

template <typename T>
struct select_container<T, std::vector> {
  using _t = std::vector<T>;  // meant for custom allocator
};

template <typename T>
struct select_container<T, std::deque> {
  using _t = std::deque<T>;  // custom allocator should also go here
  [[deprecated("We won't stop you from using deque, but please think twice "
               "(link to wiki).")]]
  constexpr static inline int __bad() {
    return 0;
  }
  enum { _bad = __bad() };
};

int foo() {
  select_container<int, std::vector>::_t vector_version;
  // select_container<int, std::deque>::_t deque_version;
  return vector_version[0];
}

这可以使用 g++7 完成工作(deque_version在代码中时会发出警告,并且只要它被注释掉就不会发出警告)。但是,使用 g++-8 和 clang++ 5 到 8 时,总是会发出警告,即使select_container实例化 no 时(即foo从源中删除时)也是如此。请参阅 compiler-explorer

标签: c++templatesg++clang++gcc-warning

解决方案


使用别名上的属性:

template <typename T>
struct  select_container<T, std::deque> {
  using _t [[deprecated("We won't stop you from using deque, but please think twice "
               "(link to wiki).")]] = std::deque<T>;  // custom allocator should also go here
};

这适用于 gcc 和 clang 主干。演示


推荐阅读