c++ - 使用 SFINAE、约束或概念来限制特化?

标签 c++ template-specialization sfinae c++-concepts template-function

以下程序运行良好:

struct M; // forward declare so compiler will recognize this type
struct N;

template< typename J > struct B { template< typename U > void Func1(); };

template<> template<> void B< M >::Func1< M >() {}
template<> template<> void B< N >::Func1< N >() {}
template<> template<> void B< M >::Func1< N >() {} // illegal specialization for this app

template< typename J > struct C { template< typename U > void Func2(); };

template<> template<> void C< M >::Func2< M >() {}
template<> template<> void C< N >::Func2< N >() {}

template< typename G > struct H { G g; };

int main()
{
  H< B< M > > hbm;
  hbm.g.Func1< M >(); // ok
  hbm.g.Func1< N >(); // compiles and runs, but uses a semantically illegal specialization for this app

  H< B< N > > hbn;
  hbn.g.Func1< N >(); // ok

  H< C< M > > hcm;
  hcm.g.Func2< M >(); // ok

  H< C< N > > hcn;
  hcn.g.Func2< N >(); // ok

  return 0;
}

重要的是,必须在编译时显式声明结构 B 和 C,并且只允许那些对应用有意义的专门化。

但从上面的代码中可以看出,我的下游开发人员(有一天!)可能能够创建语法上正确的模式,但在语义上没有意义。具体来说,应用程序只知道如何使用类和函数类型相同的类型。其余的都是无稽之谈。

这似乎是新的 C++17+ 功能之一的案例,例如 SFINAE、约束或概念。尽管我正在阅读这些内容,但我还没有做出选择的判断力。在替代方案下的 cppreference 中,如果编译器有能力(我使用 VS2015),他们建议使用 Concepts 而不是 SFINAE。

将类型名 J 限制为与类型名 U 相同的好方法是什么?

最佳答案

您可以使用enable_if :

template< typename J > struct B {     
    template<typename U>
    typename std::enable_if<std::is_same<U, J>::value, void>::type
    Func1();
};

http://coliru.stacked-crooked.com/a/efb499cf654f0f25

有了概念(在不久的将来不会成为标准),与上面相同的解决方案将如下所示。

http://melpon.org/wandbox/permlink/li4Uh5Q6ilpnlhcl

template <class T, class U> concept bool Same = std::is_same<T,U>::value;

template< typename J > struct B { 
    template< typename U > 
    requires Same<J, U>    
    void Func1(); 
};

关于c++ - 使用 SFINAE、约束或概念来限制特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37422423/

相关文章:

c++ - 模板常量类型转换运算符在 linux (gcc) 下不起作用

c++ - 如何在 Qt-Creator 中正确使用 mpfr/gmp?

c++ - 模板类中的类模板特化

c++ - 重载函数不编译的简单 SFINAE 示例

c++ - 使用 SFINAE 有条件地解析分配器成员

c++ - 常量 T & 与 T & 常量。有什么不同?

c++ - 此代码无输出

c++ - 函数特化/重载规则示例

c++ - std::hash 特化使用 sfinae?

c++ - 使用泛型类专门化模板函数