VS 2012的嵌套名称空间混乱

时间:2018-09-03 09:46:24

标签: c++ visual-studio-2012 namespaces

我在使用VS 2012编写一个非常简单的代码时遇到问题。我在centOS 7,Debian 8、9,Fedora 25、26、27、28和Ubuntu 14.04、16.04、18.04上都使用了最新的GCC和官方软件包中的Clang编译器,以及在VS 2013,VS 2015,VS 2017中使用的Clang编译器。

这是内含代码的最低版本:

file0.h

namespace B {
    enum bar {
        HELLO,
        WORLD
    };
}

file1.h

namespace A {
namespace B {
    // Some stuff
}
}

file2.h

#include "file0.h"

namespace A {
namespace C {

    template<::B::bar = ::B::HELLO> class foo {
        // Some stuff
    };    
}
}

main.cpp

#include <iostream>
#include "file0.h"
#include "file1.h"
#include "file2.h"

int main() {
    ::A::C::foo<> myFoo;
    // Some stuff
}

此代码在VS 2012上导致以下编译错误:

  

错误C2039:'bar':不是'A :: B'的成员

因为我们在file2.h的命名空间::A::C中(因此也在命名空间::A中)并要求命名空间::B,所以VS 2012似乎忽略了::B之前,并首先在当前名称空间::A中搜索。由于在bar中找不到::A::B,因此它只会引发错误,而不是在更高级别的范围内进行搜索。

鉴于堆栈溢出的following answer,在具有名称空间解析的VS 2012中似乎有一个错误。

我的问题是:

有没有一种方法可以解决此问题而无需更改名称空间的名称(对我来说,将B保留在:: B和:: A :: B中非常重要)?像使用其他语法来使用名称空间,还是使用别名名称空间?

注意:错误复制的代码已被编辑(与我的原始帖子相比,它实际上涉及第三个文件file0.h。我的错误)。

1 个答案:

答案 0 :(得分:1)

我无法在Visual 2013和2008上重现此错误。 这似乎是2010年和2012年的一个特定问题。

也许在命名空间声明之外尝试typedef:

function cidrToRange($cidr) {
  $range = array();
  $cidr = explode('/', $cidr);
  $range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
  $range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
  return $range;
}


function t1($val, $min, $max) {
    return ($val >= $min && $val <= $max);
}

    foreach($ARRAY as $ACCOUNTING) {
        $ip_src = $ACCOUNTING['src-address'];
        $ip_src_int = ip2long($ACCOUNTING['src-address']);
        $ip_dst = $ACCOUNTING['dst-address'];
        $ip_dst_int = ip2long($ACCOUNTING['dst-address']);
        $bytes = $ACCOUNTING['bytes'];


        $cidr = "8.8.8.8/32, 8.8.4.4/32, 192.168.0.0/16";
        $cidr_strip_space = preg_replace('/\s+/', '', $cidr);
        $cidr_array_explode = explode(',', $cidr_strip_space);

        foreach($cidr_array_explode as $cidr_array){
            $exclude_ip = cidrToRange($cidr_array);
            $exclude_ip_start_int = ip2long($exclude_ip[0]);
            $exclude_ip_start = $exclude_ip[0]; 
            $exclude_ip_end_int = ip2long($exclude_ip[1]);
            $exclude_ip_end = $exclude_ip[1]; 
        }

        //Check if ip in use UPLOAD
        $query = "SELECT id, ipv4 FROM services WHERE ipv4='$ip_src' AND deleted !='1'";
        $result = mysqli_query($conn, $query);
        $row = mysqli_fetch_array($result);


        if(mysqli_num_rows($result) > 0) {
            $service_id = $row['id'];
            //Update Download Traffic
            $check_if_exist_query = "SELECT * FROM traffic_counters WHERE service_id='$service_id' AND date=CURRENT_DATE()";
            $check_result = mysqli_query($conn, $check_if_exist_query);
            $check_num_rows = mysqli_num_rows($check_result);

            if($check_num_rows == 0) {
                $add_query = "INSERT INTO traffic_counters (service_id, upload_bytes, date) VALUES ('$service_id', '$bytes', CURRENT_DATE());";
                $add_result = mysqli_query($conn, $add_query);
            } else {
                $update_query = "UPDATE traffic_counters SET 
                                    upload_bytes = upload_bytes + $bytes
                                    WHERE service_id='$service_id' AND date=CURRENT_DATE();
                                ";
                $update_result = mysqli_query($conn, $update_query);
            }
        }

        //Check if ip in use DOWNLOAD
        $query = "SELECT id, ipv4 FROM services WHERE ipv4='$ip_dst' AND deleted !='1'";
        $result = mysqli_query($conn, $query);
        $row = mysqli_fetch_array($result);

        if(mysqli_num_rows($result) > 0) {
            $service_id = $row['id'];
            //Update Download Traffic
            $check_if_exist_query = "SELECT * FROM traffic_counters WHERE service_id='$service_id' AND date=CURRENT_DATE()";
            $check_result = mysqli_query($conn, $check_if_exist_query);
            $check_num_rows = mysqli_num_rows($check_result);

            if($check_num_rows == 0) {
                $add_query = "INSERT INTO traffic_counters (service_id, download_bytes, date) VALUES ('$service_id', '$bytes', CURRENT_DATE());";
                $add_result = mysqli_query($conn, $add_query);
            } else {
                $update_query = "UPDATE traffic_counters SET 
                                    download_bytes = download_bytes + $bytes
                                    WHERE service_id='$service_id' AND date=CURRENT_DATE();
                                ";
                $update_result = mysqli_query($conn, $update_query);
            }
        }
    }