3

考虑以下模板:

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”部分从未为不可复制分配的类型运行,这也无法编译。我应该怎么做?

4

1 回答 1

3

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

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<T>(),并且我使用覆盖调度来选择我要使用的实现。

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

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

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

于 2013-08-08T19:12:01.460 回答