c++ 基于编译时常量禁用/隐藏模板中的函数

djmepvbi  于 2023-07-01  发布在  其他
关注(0)|答案(3)|浏览(118)

是否可以使用编译时常量有条件地隐藏或禁用模板类中的函数?
假设下面的类:

template<size_t M, size_t N>
class MyClassT
{
    // I only want this function available if M == N, otherwise it is illegal to call
    static MyClassT<M, N> SomeFunc()
    {
        ...
    }
}

MyClassT<2,2>::SomeFunc(); // Fine
MyClassT<3,2>::SomeFunc(); // Shouldn't even compile
ih99xse1

ih99xse11#

使用部分专门化和继承:

// Factor common code in a base class
template <size_t n, size_t m>
class MyClassTBase
{
    // Put here the methods which must appear
    // in MyClassT independantly of n, m
};

// General case: no extra methods
template <size_t n, size_t m>
class MyClassT : MyClassTBase<n, m>
{};

// Special case: one extra method (you can add more here)
template <size_t n>
class MyClassT<n, n> : MyClassTBase<n, n>
{
    static MyClassT<n, n> SomeFunc()
    {
        ...
    }
};

另一种选择是使用SFINAE:std::enable_if或其变体:

template <size_t n, size_t m>
class MyClassT
{
    template <typename EnableIf = char>
    static MyClassT<n, m> SomeFunc(EnableIf (*)[n == m] = 0)
    {
        ...
    }
};

更详细的替代方案(但如果您不了解SFINAE和指向数组的指针,就不会感到惊讶)是

template <size_t n, size_t m>
class MyClassT
{
    template <typename Dummy = char>
    static MyClassT<n, m>
    SomeFunc(typename std::enable_if<n == m, Dummy>::type * = 0)
    {
        ...
    }
};

通常,我更喜欢SFINAE方法,其中有一个或两个成员函数要启用或禁用。一旦它变得比这更复杂,我更喜欢部分专门化技术。

  • 编辑:* SFINAE代码是错误的,因为没有模板函数。更正。
6ju8rftf

6ju8rftf2#

提供专门化的理想方法是使用模板专门化。你可以将所有的基本功能移到基类中:

template< size_t M, size_t N >
class basic_class{ ... };

template< size_t M, size_t N >
class my_class : basic_class< M, N > { ... };

template< size_t M >
class my_class< M, M > : basic_class< M, N > { ... };

或者,您可以添加一个虚拟模板参数并使用enable_if

template< typename Dummy = int >
typename std::enable_if< M == N, my_class >::type some_func( Dummy* = 0 );
6psbrbz9

6psbrbz93#

在C++20中,可以使用constraint

template<size_t M, size_t N>
class MyClassT
{
    static MyClassT<M, N> SomeFunc() requires (M == N)
    {
        // ...
    }
};

相关问题