2016-12-05 46 views
2

我正在實驗::可選<>可變的恆定參考,但是當我使用操作員 - >()上它,我有一個編譯錯誤,但只有當使用鐺++ libstdC++不能使用的實驗::可選恆定的基準的libstdC++

#include <experimental/optional> 
#include <iostream> 
#include <vector> 

int main(void) 
{ 
    std::experimental::optional<std::vector<int>> opt; 
    const auto &rf = opt; 

    opt.emplace(); 
    opt->push_back(1); 

    std::cout << "opt->size() = " << opt->size() 
       << " rf->size() = " << rf->size() << "\n"; 

    return 0; 
} 

運行這個程序:顯然不恆定的引用都OK:

$ clang++ -W -Wall -std=c++14 -stdlib=libc++ test.cc && ./a.out 
opt->size() = 1 rf->size() = 1 # OK 

$ g++ -W -Wall -std=c++14 test.cc && ./a.out 
opt->size() = 1 rf->size() = 1 # OK 

$ clang++ -W -Wall -std=c++14 test.cc 
In file included from test.cc:1: 
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:576:16: error: call to '__constexpr_addressof' is ambiguous 
     { return __constexpr_addressof(this->_M_get()); } 
       ^~~~~~~~~~~~~~~~~~~~~ 
test.cc:14:40: note: in instantiation of member function 'std::experimental::fundamentals_v1::optional<std::vector<int, std::allocator<int> > >::operator->' requested here 
       << " rf->size() = " << rf->size() << "\n"; 
            ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:173:20: note: candidate function [with _Tp = const std::vector<int, std::allocator<int> >, $1 = <>] 
    constexpr _Tp* __constexpr_addressof(_Tp& __t) 
       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:180:17: note: candidate function [with _Tp = const std::vector<int, std::allocator<int> >, $1 = <>] 
    inline _Tp* __constexpr_addressof(_Tp& __t) 
       ^
1 error generated. 

每當我使用恆定的參考會出現此錯誤。

我使用Linux Mint的18與這些版本的G ++/++的libstdc和5.4.0鐺++ 3.8.0:

$ g++ --version 
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 
Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

$ dpkg-query -s libstdc++-5-dev 
... 
Version: 5.4.0-6ubuntu1~16.04.4 
... 

$ clang++ --version 
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 
InstalledDir: /usr/bin 

這是在我的程序中的錯誤,的libstdC++或鐺++?

更新:問題與叮噹消失3.9.0。 (正如Richard Smith和Ville Voutilainen在下面解釋的那樣,似乎libstdC++期望編譯器以不符合鏗鏘3.8.0的特定方式行事。)

回答

3

這對我來說當然看起來像一個叮噹聲bug,因爲它診斷的重載模塊具有互斥的enable_if約束,所以它們應該不可能是模糊的。

+5

'__constexpr_addressof'上的SFINAE條件要求編譯器替換爲擴展爲零元素的包。該行爲(以及一般的擴展和替換的相對順序)未由標準規定。 –

+0

啊,淫。在libstdC++中肯定可以避免這個問題。 –

+0

FWIW,我安裝了clang ** 3.9.0 **,問題消失了,這對我來說已經足夠了。 :) 感謝你的回答! – jick