【问题标题】:Typetraits and specific behaviour类型特征和特定行为
【发布时间】:2013-08-08 19:03:23
【问题描述】:

考虑以下模板:

template<class T>
void doStuff(const T& a)
    {
    if(std::is_copy_assignable<T>::value)
        {
        T x;
        x=a;
        printf("Hello\n");
        }
    else
        {
        printf("Goodbye\n");
        }
    }

即使“Hello”部分从未针对不可复制分配的类型运行,也无法编译。我应该怎么做?

【问题讨论】:

    标签: c++ templates metaprogramming typetraits


    【解决方案1】:

    这是一种基于标签调度的方法来解决您的问题:

    template<class T>
    void doStuffHelper(const T& a, std::true_type can_copy_assign)
    {
      T x;
      x=a;
      printf("Hello\n");
    }
    template<class T>
    void doStuffHelper(const T& a, std::false_type can_copy_assign)
    {
      printf("Goodbye\n");
    }
    template<class T>
    void doStuff(const T& a)
    {
      return doStuffHelper( a, std::is_copy_assignable<T>() );
    }
    

    这里只编译有效的版本。 can_copy_assign 的名称仅用于文档 - 关键是我基于 std::is_copy_assignable&lt;T&gt;() 覆盖,并且我使用覆盖调度来选择我要使用的实现。

    在您的代码中,if 块变为类似于if(true)if 块的 else 子句是 if(true) 仍然必须编译,这意味着使用的方法必须是有效的,即使它们永远不会运行。

    标签调度解决方案对其进行安排,以便具有预期属性的函数与使用这些属性的代码一起编译。

    可以使用涉及 SFINAE 的类似方法,但 SFINAE 有一些烦人的并发症,这意味着如果可能,通常最好避免它。

    【讨论】:

    • 我会加上“尽可能避免”,但有很多情况是无法避免的。
    • @DaveS 是的,并不总是可以避免它:但如果可以的话,通常是最好的。我过去曾在 Stack Overflow 上发布过一两个 SFINAE 解决方案。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2014-06-10
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多