【发布时间】:2015-07-04 00:20:22
【问题描述】:
我有一个看起来像这样的模板类:
template <typename T> constexpr bool is_value_passable_v = is_trivially_copyable_v<T> && sizeof(T) <= sizeof(void*) && !is_polymorphic_v<T>;
template <typename B, typename T> using param_base_t = conditional_t<is_value_passable_v<B>, T, const T&>;
template <typename T> struct param_d
{
using type = param_base_t<T, T>;
};
template <> struct param_d<void>
{
using type = void;
};
template <typename T> using param_t = typename param_d<T>::type;
template <class TIn> class CClass
{
public:
static constexpr bool use_input_v = !is_same_v<typename TIn::input_t, void>;
using input_t = conditional_t<use_input_v, param_t<typename TIn::input_t>, void>;
enable_if_t<use_input_v> Input(input_t i);
};
这段代码的目标是,为不同的模板参数提供不同的Input函数。
- 带有
input_t = int的模板参数应导致void Input(int i) - 带有
input_t = std::vector的模板参数应导致void Input(const std::vector& i) - 带有
input_t = void的模板参数应删除Input函数
用 clang 编译会得到
/usr/bin/../include/c++/v1/type_traits:225:78: error: no type named 'type' in 'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration
template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
^~~
编辑 1: 添加行后
template <typename T> static constexpr bool use_input2_v = use_input_v;
并将函数声明替换为
template <typename T = void> enable_if_t<use_input2_v<T>> Input(input_t i)
clang 抱怨有 no matching member function for call to 'Input':
note: candidate template ignored: substitution failure [with T = void]: non-type template argument is not a constant expression
template <typename T = void> enable_if_t<use_input2_v<T>> Input(input_t i);
~~~~~~~~~~~~ ^
编辑 2: 忘了提一下,这个错误伴随着模板参数的所有三种变体。
编辑 3:
CClass 的示例用例可以是
class CInput0
{
using input_t = int;
};
class CInput1
{
using input_t = std::vector<int>;
};
class CInput2
{
using input_t = void;
};
CClass<CInput0> in0;
CClass<CInput1> in1;
CClass<CInput2> in2;
std::vector<int> i = {1, 2, 3};
in0.Input(3);
in1.Input(i);
//in2.Input() disabled
【问题讨论】:
-
你为什么不只使用
static constexpr bool use_input_v = !is_same<typename TIn::input_t, void>;? -
而不是 use_input2_v 版本? Afaik enable_if 只能禁用基于“直接”模板的功能。
-
template <typename T> constexpr bool is_value_passable_v = is_trivially_copyable_v<T> && sizeof(T) <= sizeof(void*) && !is_polymorphic_v<T>;这是什么?它既不是函数也不是类模板。 -
对不起!这是一个 c++14 变量模板。忘记了相应的标签。
-
TIn::input_t来自哪里?或者换个方式问:你是如何实例化CClass的?
标签: templates c++11 c++14 sfinae enable-if