Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.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++_Templates_Boost_Compiler Errors - Fatal编程技术网

C++ 负数组索引和看似冗余的模板使用

C++ 负数组索引和看似冗余的模板使用,c++,templates,boost,compiler-errors,C++,Templates,Boost,Compiler Errors,我遇到了以下代码行: template< int I > struct arg { arg() { } template< class T > arg( T const & /* t */ ) { // static assert I == is_placeholder<T>::value typedef char T_must_be_placeholder[ I == is_p

我遇到了以下代码行:

template< int I > struct arg
{
    arg()
    {
    }

    template< class T > arg( T const & /* t */ )
    {
        // static assert I == is_placeholder<T>::value
        typedef char T_must_be_placeholder[ I == is_placeholder<T>::value? 1: -1 ];
    }
};

template< class T > struct is_placeholder
{
    enum _vt { value = 0 };
};

如果第一个示例中的健全性检查有效,那么第二个示例中的健全性检查如何失败?

是一个模板,因此它可以专门用于不同的
T
。假设我创建了一个结构
example
,并希望
is\u placeholder::value
为42。我会这样做:

struct example {};

template< class T > struct is_placeholder
{
    enum _vt { value = 0 };
};

template<>
struct is_placeholder<example>
{
    enum _vt { value = 42 };
};

template< int I > struct arg
{
    arg()
    {
    }

    template< class T > arg( T const & /* t */ )
    {
        // static assert I == is_placeholder<T>::value
        typedef char T_must_be_placeholder[ I == is_placeholder<T>::value ? 1: -1 ];
    }
};

void test()
{
    auto x = arg<42>(example()); // compiles
    auto y = arg<43>(example()); // assertion
    return 0;
}
struct-example{};
模板结构是\u占位符
{
枚举_vt{value=0};
};
模板
结构是一个占位符
{
枚举_vt{value=42};
};
模板结构参数
{
arg()
{
}
模板arg(T常量&/*T*/)
{
//静态断言I==is_占位符::值
typedef char T_必须是占位符[I==is_占位符::值?1:-1];
}
};
无效测试()
{
auto x=arg(示例());//编译
auto y=arg(示例());//断言
返回0;
}
在这种情况下,
T\u must\u be\u placeholder
检查
is\u placeholder::value
(我们刚才专门定义为42)是否与
I
相同。所以,如果
I
是42,它就编译,但是如果
I
是其他任何东西,它就不会编译


试图创建一个大小为负的数组是故意阻止代码编译的一种方式,因此,是的,这可能是一种健全性检查(如注释中所述,是静态断言)。

是一个占位符
是一个模板,可以专门用于不同的
T
。假设我创建了一个结构
example
,并希望
is\u placeholder::value
为42。我会这样做:

struct example {};

template< class T > struct is_placeholder
{
    enum _vt { value = 0 };
};

template<>
struct is_placeholder<example>
{
    enum _vt { value = 42 };
};

template< int I > struct arg
{
    arg()
    {
    }

    template< class T > arg( T const & /* t */ )
    {
        // static assert I == is_placeholder<T>::value
        typedef char T_must_be_placeholder[ I == is_placeholder<T>::value ? 1: -1 ];
    }
};

void test()
{
    auto x = arg<42>(example()); // compiles
    auto y = arg<43>(example()); // assertion
    return 0;
}
struct-example{};
模板结构是\u占位符
{
枚举_vt{value=0};
};
模板
结构是一个占位符
{
枚举_vt{value=42};
};
模板结构参数
{
arg()
{
}
模板arg(T常量&/*T*/)
{
//静态断言I==is_占位符::值
typedef char T_必须是占位符[I==is_占位符::值?1:-1];
}
};
无效测试()
{
auto x=arg(示例());//编译
auto y=arg(示例());//断言
返回0;
}
在这种情况下,
T\u must\u be\u placeholder
检查
is\u placeholder::value
(我们刚才专门定义为42)是否与
I
相同。所以,如果
I
是42,它就编译,但是如果
I
是其他任何东西,它就不会编译


尝试创建一个大小为负的数组是故意阻止代码编译的一种方式,因此是的,这可能是一种健全性检查(如注释中所述,是静态断言)。

这是一个穷人对静态断言的实现。如果不满足某些条件,将声明一个大小为负的数组,这将触发编译错误。您的上一个示例不应编译,因为数组的大小不是常量表达式。这可能是因为GCC扩展,不确定传递负大小时会发生什么。令人惊讶的是,这确实可以编译。这是一个穷人实现的静态断言。如果不满足某些条件,将声明一个大小为负的数组,这将触发编译错误。您的上一个示例不应编译,因为数组的大小不是常量表达式。这可能是因为GCC扩展,不确定传递负大小时会发生什么。令人惊讶的是,这确实可以编译。查看。关于为什么
是\u占位符
是模板化的?对不起,我在使用模板方面有点经验不足:|为什么不
inti=0;字符a[i==1?1:-1]然后失败?@SauravSahu,因为这样您就有了VLA(用于运行时已知大小的阵列的gcc扩展)。如果设置i const,您将得到一个错误,我怀疑这是因为
i
不是静态已知的,这会导致在运行时在堆栈上分配一个可变大小的数组,而不是编译错误。请参阅@user634175,如果您所说的“静态已知”是指“在编译时已知”,那么您的怀疑是正确的:pAbout为什么
是\u占位符
是模板化的?对不起,我在使用模板方面有点经验不足:|为什么不
inti=0;字符a[i==1?1:-1]然后失败?@SauravSahu,因为这样您就有了VLA(用于运行时已知大小的阵列的gcc扩展)。如果设置i const,您将得到一个错误,我怀疑这是因为
i
不是静态已知的,这会导致在运行时在堆栈上分配一个可变大小的数组,而不是编译错误。请参阅@user634175,如果“静态已知”的意思是“在编译时已知”,那么您的怀疑是正确的:p