【问题标题】:Will static_if deprecate template specialization?static_if 会否决模板专业化?
【发布时间】:2012-08-22 20:33:51
【问题描述】:

一些常见的模板特化如下:

template<class T>
class C
{
    void common() { ... }
    void f2 = delete;
};

template<>
class C<int>
{
    void common() { ... }
    void f1() { ... }
};

可以用static_if 表示为:

template<class T>
class C
{
    void common() { ... }

    static_if(std::is_same<T, int>::value)
    {
        void f1( ) { ... }
    }
    else
    {
        void f2( ) = delete;
    }
}

这些是直接竞争的功能吗?模板专业化可以做一些static_if 做不到的事情吗?似乎static_if 可以做模板专业化可以做的所有事情,甚至更多。

顺便说一句:在这种情况下,我不太喜欢static_if,因为它可能使您在任何给定情况下都可以使用界面的哪些部分并不明显。也许模板特化在某些情况下仍然提供更清晰的语法。

【问题讨论】:

  • @Mechanical snail C++17 出了什么问题?
  • 这是多余的,因为你也有c++1y。我认为 C++0x/C++11 标签发生的事情是我们在 C++0x 上进行了标准化,直到它最终确定,此时它被重命名为 C++11。
  • 但想想看,我们可以为 C++1y、C++17、C++2x 甚至 C++2y 设置标签!
  • Methinks C++4x 最有可能。

标签: c++ templates template-specialization c++14 static-if


【解决方案1】:

static if 不会为您做的一件事是使用模板专业化的“主要”方式——在一个地方提供通用行为并让代码的用户覆盖(=专门)它以满足他们的特定需求/数据类型/等...

【讨论】:

    【解决方案2】:

    不,static_if 不会弃用显式模板特化。显式模板专业化是比 static_if 更强大的功能,提供了许多 static_if 不打算提供的功能。 static_if 只是一种更方便、更易读的方式来表达某些东西。

    static_if 不能做一些显式模板特化可以做的事情,比如改变类继承的基类。

    struct S {};
    
    template<typename T>
    struct T
      static_if(is_same<T,int>::value) { : S }  // ?
    { };
    
    template<typename T>
    struct T {};
    
    template<>
    struct T<int> : S {};
    

    【讨论】:

    • 我认为你可以用 std::conditional 做到这一点 - 如果唯一的区别是改变你可能想要的基类。
    • 你可以选择从一个类或另一个类继承,但我不认为你可以选择从一个类继承或根本不继承。
    • 我认为你是对的。 +1 表示合法的能力专业化有,static_if 没有。你能支持你的说法,即有很多吗?
    【解决方案3】:

    Ifs 是关于分支的;专业化是关于匹配的。有时一个比另一个更好。

    这是直接来自 Alexandrescu 的 Modern C++ Design 第 11.9 节“多方法”的示例:假设您有一个基于 Shape 的复杂类层次结构,具有虚拟和非虚拟继承。您希望能够尽可能高效地在层次结构成员之间进行转换。由于虚拟基地需要dynamic_cast,我们必须允许这样做,但我们也希望尽可能使用static_cast。通过演员政策解决:

    template <typename To, typename From> struct ShapeCaster
    { 
        static To & cast(From & x) { return dynamic_cast<To&>(x); }
    };
    
    template <> struct ShapeCaster<Triangle, Shape>
    {
        static Triangle & cast(Shape & x) { return static_cast<Triangle&>(x); }
    };
    
    template <typename To, typename From> To & shape_cast(From & x)
    {
        return ShapeCaster<To, From>::cast(x);
    }
    

    现在无论你在你的层次结构中移动,你可以说

    To & y = shape_cast<To>::cast(x);
    

    你得到最有效的演员表,并且可以轻松扩展策略。

    用一系列ifs 写这篇文章会更难阅读。

    【讨论】:

    • 我必须用static_if 写出来比较。我将static_if 放入shape_cast 以完成它,它看起来很干净。它也是大约 1/4 的代码,因为它有一个外部结构作为实现。我并不是说外部结构不好,这是目前最好的方法。但我认为我不同意这个例子(自己发布static_if 版本进行比较)。
    • 我也不同意你的第一句话。你写了多少次if(x == y)(或同等学历)? ifs 是关于分支匹配。
    • @Dave:不过这更像if (x == a || x == b || x = d)!模板让您可以为一般情况指定主要情况,然后以非侵入性的方式添加异常。换句话说,您永远不必碰if 语句。
    【解决方案4】:

    static if 功能甚至还没有成为标准。现在,假设相关问题得到解决并成为标准,并且所有编译器都支持它,那么它将只是工具集中的一个工具。

    我可以想象不同的情况,专业化会使代码更具可读性/可维护性,在所有这些情况下,专业化仍然是要走的路。请注意,static if 的最大优势是您可以交错来自不同专业化的代码,但这也可能是一个劣势,因为您可能会得到一大堆代码,而不是拥有多个简单的专业化有条件地编译/忽略。

    【讨论】:

    • 如果您有专业化更好的案例,请发布
    • @Dave:只需选择一个大类,例如 std::vector 并考虑您是否愿意在它自己的包含文件(550行不是整个文件,只是 specialization!),还是 2000 行 std::vector 实现与 static if (same_type&lt;T,bool&gt;::value) 交错?
    【解决方案5】:

    我相信是的。 static_if 比模板特化强大得多,尤其是当您需要特化类的一小部分而不是整个定义时。专业化更好的唯一情况 - 当您的专业化实现与主模板/其他专业化完全不同时。

    【讨论】:

      【解决方案6】:

      不考虑偏好,仅如果它可以使用其他模板专业化!

      众所周知:std::is_same&lt;T, int&gt;::value 本身就是模板特化!

      我不确定,但我认为它的实现方式如下:

      template<typename, typename>
      struct is_same{
          static constexpr bool value = false;;
      };
       template<typename T>
      struct is_same<T, T>{
          static constexpr bool value = true;;
      };
      

      真正的问题是,最终是否会有一种无需模板专门化的类型/类比较方法?或许只有这样才不需要模板特化!

      【讨论】:

        猜你喜欢
        • 2020-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-28
        • 2015-08-01
        • 2019-08-19
        相关资源
        最近更新 更多