首页 > 解决方案 > 自动模板推导中的 const 正确性

问题描述

在下面的示例中,我希望该行将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

第二行是假而不是真。那么为什么自动模板推导会丢弃 cv 限定词呢?发生这种情况有什么具体原因吗?

PS。上面的例子可以在这里找到

标签: c++templatesgccclangc++17

解决方案


对类型的扣除T总是会衰减的。的衰减类型int const是简单的int。a 的衰减类型int[3]int*

问题是,这段代码正确的。

是的,在里面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&这样才能推导出来。


推荐阅读