2017-07-25 122 views
3

我正在尝试使用新的C++ 17类模板演绎,它似乎一切正常,直到我应用常量。这是我现在面临的麻烦一个小例子:C++ 17类模板演绎常量

#include <type_traits> 

template <typename T> 
struct X 
{ 
    T _data; 

    X(void) = default; 
    X(T && data) : _data{ data } {} 

    constexpr bool const_x(void) { return false; } 
    constexpr bool const_x(void) const { return true; } 
}; 

template <typename T> 
X(T &&) -> X<std::remove_reference_t<T>>; 

int main(void) 
{ 
    X<int> a; 
    const X<int> b{}; 

    X c{ 10 }; 
    const X d{ 10 }; 

    static_assert(!a.const_x()); 
    static_assert(b.const_x()); 

    static_assert(!c.const_x()); 
    static_assert(d.const_x()); // assert fails 
} 

看来,当一个const X被演绎它的类型,在常量性是没有得到贯彻。我知道这是可能的:

template <typename T> 
X(T &&) -> const X<std::remove_reference_t<X>>; 

但这将尽一切推断类型为const X.

如果任何人有任何信息或帮助,将不胜感激!

编辑我使用GCC-7.1.0

+0

https://godbolt.org/g/kRdTpJ铿锵树干没有问题与您的代码。 gcc主干也没有问题:https://godbolt.org/g/TpneVq看起来只是一个编译器错误。推测你是用gcc 7.1来试试的? https://godbolt.org/g/j6W3dB(在该行失败) – xaxxon

+0

编译时是否有任何错误?还是只在执行过程中? – Fenixrw

+0

@Fenixrw这是一个静态断言失败 - 这只是一个编译时问题 – xaxxon

回答

8

这是一个编译器错误 - 特别gcc bug 80990。这里有两个单独的部分 - 扣除和const。的声明:

const X d{ 10 }; 

将首先执行类模板参数推导挑选哪个X专业化d是(这样X<int>由于扣导向件),然后将被const最重要的是(这样X<int> const)加入。


还要注意的是这样的:

template <typename T> 
X(T &&) -> const X<std::remove_reference_t<X>>; 

是形成不良。你不能在那里使用cv-qualifiers。