对于带有3个通用参数的模板,使用std :: enable if

时间:2014-09-15 14:54:19

标签: c++ templates enable-if

我已经找到了std::enable_if主题的一些主题,但遗憾的是我无法将这些示例应用到我的代码中。

template<class From, class To, class Value>
struct convert
{
  static Value apply(Value value)
  {
    return value;
  }
};

我希望仅当FromTo相同时才启用此功能,因此我尝试使用

std::enable_if<std::is_same<From,To>::value>::Value

但这并不奏效。我该怎么做?

我也有这两个专业,让你更好地了解我的问题:

template<class From, class Value>
struct convert<From, kilometer, Value>
{
  static Value apply(Value value)
  {
    doSomething;
  }
};

template<class To, class Value>
struct convertImpl <kilometer, To, Value>
{
  static Value apply(Value value)
  {
    doSomethingElse;
  }
};

这是我的abguity问题的来源。现在我静态地认为FromTo是相同的,从而使代码编译。但是当这两个属性相同时,我想返回值。

2 个答案:

答案 0 :(得分:4)

我认为你不想要SFINAE,根据你的描述我认为你只想要专业化:

template<class From, class To, class Value>
struct convert
{
    static Value apply(Value value)
    {
        Value somethingElse = ...;
        return somethingElse;
    }
};

template<class From, class Value>
struct convert<From,From,Value>
{
    static Value apply(Value value)
    {
        return value; // SAME
    }
};

我承认我真的没有在这里看到这种感觉,因为Value是来自FromTo的独立类型,但你可能对它有所了解我没有。如果你想要完整的结构专用,这似乎是你的愿望。 See it live

祝你好运

答案 1 :(得分:3)

template<class From, class To, class Value>
struct convert
{
    template <typename F = From, typename T = To>
    static auto apply(Value value) -> typename std::enable_if<std::is_same<F,T>::value, Value>::type
    {
        static_assert(std::is_same<F, From>::value && std::is_same<T, To>::value, "");
        // no conversion
        return value;
    }

    template <typename F = From, typename T = To>
    static auto apply(Value value) -> typename std::enable_if<!std::is_same<F,T>::value, Value>::type
    {
        static_assert(std::is_same<F, From>::value && std::is_same<T, To>::value, "");
        // do conversion
        return value;
    }
};

DEMO

或者,这可以使用基于标签的调度来实现:

template<class From, class To, class Value>
struct convert
{
    static Value apply(Value value)
    {
        using tag = std::integral_constant<bool, std::is_same<From, To>::value>; 
        return _apply(value, tag{});
    }

private:
    static Value _apply(Value value, std::true_type)
    {
        // no conversion
        return value;
    }

    static Value _apply(Value value, std::false_type)
    {
        // do conversion
        return value;
    }
};

DEMO 2