Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何基于类模板参数禁用成员函数?_C++_Class_Templates_Sfinae - Fatal编程技术网

C++ 如何基于类模板参数禁用成员函数?

C++ 如何基于类模板参数禁用成员函数?,c++,class,templates,sfinae,C++,Class,Templates,Sfinae,为了说明这种情况,让我们假设一个最小的例子:一个向量模板类将其维度作为非类型模板参数。当维度允许时,此类将提供x(),y()(等)访问器: template <int N_dimension> class Vector { public: // ctors, etc. int &x(); template <class = std::enable_if_t<(N_dimension>2)>> int &y

为了说明这种情况,让我们假设一个最小的例子:一个
向量
模板类将其维度作为非类型模板参数。当维度允许时,此类将提供
x()
y()
(等)访问器:

template <int N_dimension>
class Vector
{
public:
    // ctors, etc.    
    int &x();

    template <class = std::enable_if_t<(N_dimension>2)>> int &y();

private:
    std::array<int, N_dimension> mData;
};
此外,它还需要在定义中使用静态断言来确保它是傻瓜式的(因为现在客户端代码可以为
N
提供与真实维度不匹配的显式值。Edit:或者为匿名第二个模板参数提供显式值,正如SergeyA所指出的)



< C++ > C++中有一种更直接的方法来表示这一点吗?

< p>,你可以简单地使用<代码>要求< /C> >丢弃方法:

template <int N>
class Vector
{
public:
    int &x();
    int &y() requires(N >= 2);

private:
    std::array<int, N_dimension> mData;
};
模板
类向量
{
公众:
int&x();
int&y()需要(N>=2);
私人:
std::数组mData;
};
在以前的版本中,它更详细:

template <std::size_t N>
class Vector
{
public:
    int &x();

    template <std::size_t M = N, std::enable_if_t<(M >= 2 && M == N), int> = 0>
    int &y();

private:
    std::array<int, N_dimension> mData;
};
模板
类向量
{
公众:
int&x();
模板=0>
int&y();
私人:
std::数组mData;
};

我想在这里废除SFINAE,只需将代码分成接口和私有实现,如下所示:

int& y() {
    return y_impl(std::bool_constant<N > 2>{});
}

private:
int& y_impl(std::true_type ) {
    // impl
}
int& y_impl(std::false_type ) {
    static_assert(N > 2 /* always false */, "Wrong number of dimensions!");
}
int&y(){
返回y_impl(std::bool_常量2>{});
}
私人:
int&y_impl(标准::真_类型){
//恳求
}
int&y_impl(std::false_类型){
静态断言(N>2/*始终为false*/,“维数错误!”);
}

这里的分割是在假定
y
不可编译的情况下进行的,而
N专门化是唯一的其他选项。但“笨重”的选择真的没有那么多;我不担心有人指定显式模板参数。这就是注释和文档的用途。放一条注释,上面写着:不要指定任何参数,别管它们。您还有另一个缺陷-通过将显式类型作为第二个模板参数,客户端也可以实例化该函数。既然在
N\u维度
大于2的情况下,您似乎没有专门启用其他
y()
,那么您为什么需要它呢?只需保留
static\u assert
,这比模板替换错误的行和行更具描述性。哦,的确,删除了输入错误。这种方法的一个限制是没有实际删除成员函数,这使得(据我所知)无法使用诸如
int& y() {
    return y_impl(std::bool_constant<N > 2>{});
}

private:
int& y_impl(std::true_type ) {
    // impl
}
int& y_impl(std::false_type ) {
    static_assert(N > 2 /* always false */, "Wrong number of dimensions!");
}