Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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++ 为什么编译器在编译时无法理解if分支的值?_C++_Templates_C++11 - Fatal编程技术网

C++ 为什么编译器在编译时无法理解if分支的值?

C++ 为什么编译器在编译时无法理解if分支的值?,c++,templates,c++11,C++,Templates,C++11,我在写一个计算多维向量元素的函数 template<class T> int real_size(const std::vector<T>& vec) { int size=0; for(const auto& v : vec) { if(std::is_integral<T>::value || std::is_floating_point<T>::value

我在写一个计算多维向量元素的函数

template<class T>
int real_size(const std::vector<T>& vec)
{
    int size=0;
    for(const auto& v : vec)
    {
        if(std::is_integral<T>::value ||
                std::is_floating_point<T>::value){
            size+=1;
        }
        else{
            size +=real_size(v);
        }
    }
    return size;
}

int main()
{
    std::vector<std::vector<int>> a(10);
    a[0]=std::vector<int>(10);
    std::cout<<real_size(a);
}
代码看起来很好,错误是无关的……else语句永远不应该变成
size+=real\u size(int)std::is_integer
检查模板参数的类型

但编译器似乎无法在编译时理解它!!是编译器错误还是我犯了错误


*我使用的是GCC4.8.1。g++-std=c++11*

错误是因为
else
分支仍然需要编译。您可以将其更改为两个不同的函数,然后使用标记分派:

template<class T>
int real_size(const std::vector<T>& vec)
{
    int size=0;
    for(const auto& v : vec)
    {
        size += real_size_inner(std::is_arithmetic<T>(), v);
    }
    return size;
}

template<class T>
int real_size_inner(std::true_type, T&)
{
    return 1;
}

template<class T>
int real_size_inner(std::false_type, T& v)
{
    return real_size(v);
}
模板
整数实值大小(常量标准::向量和向量)
{
int size=0;
用于(常数自动和v:vec)
{
大小+=实际大小内部(std::is_算术(),v);
}
返回大小;
}
样板
整型实数大小内部(标准::实数类型,T&)
{
返回1;
}
样板
内部真实尺寸内部(标准::错误类型,T&v)
{
返回实际大小(v);
}

如果您对标准中如何实现
std::advance
进行一些研究,您将了解它是如何工作的,因为它是以相同的方式实现的。

错误是因为仍然需要编译
else
分支。您可以将其更改为两个不同的函数,然后使用标记分派:

template<class T>
int real_size(const std::vector<T>& vec)
{
    int size=0;
    for(const auto& v : vec)
    {
        size += real_size_inner(std::is_arithmetic<T>(), v);
    }
    return size;
}

template<class T>
int real_size_inner(std::true_type, T&)
{
    return 1;
}

template<class T>
int real_size_inner(std::false_type, T& v)
{
    return real_size(v);
}
模板
整数实值大小(常量标准::向量和向量)
{
int size=0;
用于(常数自动和v:vec)
{
大小+=实际大小内部(std::is_算术(),v);
}
返回大小;
}
样板
整型实数大小内部(标准::实数类型,T&)
{
返回1;
}
样板
内部真实尺寸内部(标准::错误类型,T&v)
{
返回实际大小(v);
}

如果您对标准中如何实现
std::advance
进行一些研究,您将了解它是如何工作的,因为它是以相同的方式实现的。

如果您用常量的实际值替换常量,您可以看到编译错误是如何产生某种意义的。对于
int
,该代码等同于以下代码:

    if(true || false){
        size+=1;
    }
    else{
        size +=real_size(v);
    }

在这里,编译器仍然会抱怨else主体无效:死代码必须仍然是有效代码。

如果用常量的实际值替换常量,您可以看到编译错误是如何产生某种意义的。对于
int
,该代码等同于以下代码:

    if(true || false){
        size+=1;
    }
    else{
        size +=real_size(v);
    }

在这里,编译器仍然会抱怨else主体无效:死代码必须仍然是有效代码。

条件代码仍然被编译,并且必须格式良好,即使在编译时可以确定它不会被执行

一种解决方案是为其他类型过载
real\u size

template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value>::type
real_size(T const &) {
    return 1;
}

条件代码仍然被编译,并且必须是格式良好的,即使在编译时可以确定它不会被执行

一种解决方案是为其他类型过载
real\u size

template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value>::type
real_size(T const &) {
    return 1;
}

else子句中的代码不是有条件编译的。仅供参考:std::is_算术@xyz不会。您正在传递一个
std::vector
作为输入参数,如何在递归调用中传递一个T?@FabioFracassi,我仍然认为
static\u如果
使这样的代码比标记分派、SFINAE或其他一些TMP方法更容易理解:/我确实看到它如何很容易被滥用,但如果使用得当,它可以使代码更短,并将内容保存在一个地方。相关:一个
else
子句中的代码不是有条件编译的。仅供参考:
std::is_算术
@xyz不会。您正在传递一个
std::vector
作为输入参数,如何在递归调用中传递一个T?@FabioFracassi,我仍然认为
static\u如果
使这样的代码比标记分派、SFINAE或其他一些TMP方法更容易理解:/我确实看到它如何很容易被滥用,但如果使用得当,它可以使代码更短,并将东西放在一个地方。相关:你是说这样的东西吗,它给出了错误的结果,结果应该是20而不是2010@xyz:根据您发布的(伪)代码的逻辑,它应该是10:1
vector
,大小为10(给出10)和9个空的(每个都给出零)。您的意思是这样的吗,它给出了错误的结果,结果应该是20而不是2010@xyz:根据您发布的(伪)代码的逻辑,它应该是10:1
向量
,大小为10(给出10)和9个空的(每个都给出零)。标准是这么说的吗?因为我在标准论文中找不到。找不到什么?说程序的整体必须是格式良好的部分?标准是这么说的吗?因为我在标准论文中找不到。找不到什么?说明整个程序必须格式良好的部分?