自动模板推导中的常量正确性

时间:2019-12-18 17:58:15

标签: c++ templates gcc clang c++17

在下面的示例中,我希望行a.foo(j);将const限定符传递给模板化方法。

#include <iostream>
#include <type_traits>

struct A
{
    template<typename T>
    void foo(T i) const
    {
        std::cout << "Is const type: " << std::is_const<T>::value << "\n";
    }
};

int main() {

    A a;

    int i = 0;
    const int j = 0;

    a.foo(i);
    a.foo(j);

    a.foo<decltype(i)>(i);
    a.foo<decltype(j)>(j);

    a.foo<int>(i);
    a.foo<const int>(j);

    return 0;
}

但是我从gcc和clang(c ++ 17)两者获得的输出如下。

Is const type: 0
Is const type: 0
Is const type: 0
Is const type: 1
Is const type: 0
Is const type: 1

第二行是false而不是true。那么,为什么自动模板推导丢弃简历限定符?发生这种情况有什么具体原因吗?

PS。可以在上面的示例here

中找到

2 个答案:

答案 0 :(得分:3)

对类型T的推导将始终被衰减。 int const的衰减类型只是intint[3]的衰减类型为int*

问题是,此代码 const正确。

是的,在foo内您无法更改j的值。在foo内部,您有一个副本,由foo决定是否希望自己的参数在函数体内恒定。

但是,还有其他形式的推论必须使const保持可与参数一起调用。这不是您的代码的解决方案,而只是一个示例:

template<typename T>
void frob(T& i)
{
    std::cout << "Will it be const? " << std::is_const<T>::value << "\n";
}

auto main() -> int {
    int const myInt = 9;
    frob(myInt);
}

要完全被调用,参数必须为int const&,这就是要推导的内容。

答案 1 :(得分:-1)

我已解决您的问题,您需要使用参考传递“ i”。 无效foo(T&i)const