【问题标题】:Checking if a variable is constant qualified检查变量是否为常量限定
【发布时间】:2015-12-27 11:12:29
【问题描述】:

我正在阅读有关 const_cast 的内容,它似乎不安全且没有多大帮助。 SO 中关于它的best answer 声明它在这样的场景中很有用:

void func(const char* param, bool modify){
    if(modify)
        //const_cast and change param
    // stuff that do not change param
}

虽然这是一种可能的用途,但它也有风险,因为您必须正确地提供“修改”的值,否则您将获得未定义的行为,因为您正在更改本应保持不变的内容。我想知道您是否可以在不必提供这个额外参数的情况下实现相同的功能,为此您很可能需要检查 const 限定符的存在。

我发现的 closes 是 std 函数is_const,但它似乎仅限于另一种用法:

is_const<const int>::value //returns true
is_const<int>::value // returns false
const int myVar=1;
is_const<myVar>::value // what it would look like ( does not compile)

我也尝试过使用类似的函数签名,它们仅在“const”限定符上有所不同,但这被视为重新定义。那么有可能做到吗?如果可以,怎么做?

【问题讨论】:

    标签: c++ c++11 constants


    【解决方案1】:

    对于这种情况,我认为你可以只使用函数的两个重载:

    #include <stdio.h>
    
    void func(const char* param) {
        printf("Not modifying %c\n", param[0]);
    }
    
    void func(char* param) {
        printf("Modifying %c\n", param[0]);
        func(const_cast<const char*>(param));
    }
    
    int main() {
        const char foo[1] = {'F'};
        char bar[1] = {'B'};
    
        func(foo);
        func(bar);
    }
    

    哪些输出:

    Not modifying F
    Modifying B
    Not modifying B
    

    当调用func 时,会根据参数的常量自动选择正确的重载。在这里,我让非常量版本调用 const 版本来完成非常量部分的工作,这似乎符合原始用例,但您当然也可以让这两个版本都调用第三个(可能是私有/静态) 版本,它采用原始建议的bool modify 参数,但现在知道常量是正确的)。

    或者,如果你想使用std::is_const,你可以使用模板函数自动生成const和non-const版本并自动扣除修改参数:

    #include <stdio.h>
    #include <type_traits>
    
    static void func(char* param, bool modify) {
        if (modify)
            printf("Modifying %c\n", param[0]);
        printf("Not modifying %c\n", param[0]);
    }
    
    template<typename T>
    void func(T *param) {
        func(const_cast<char*>(param), !std::is_const<T>::value);
    }
    

    使用与第一个示例相同的 main(),这将产生与第一个示例完全相同的输出。

    【讨论】:

    • 我认为问题的关键在于避免维护一个函数的两个版本。至少这就是我正在寻找的。​​span>
    【解决方案2】:

    您可以使用std::is_const&lt;decltype(myVar)&gt;::value 来检查myVar 是否已声明为const

    但是,如果 myVar 是指针或对另一个对象的引用,则无法从函数内部知道该对象是否为 const

    【讨论】:

    • remove_reference_t 有时也很有用。
    • 我不确定 OP 是否理解它的正确用法。在提供的示例中,它不会以任何方式帮助 OP :)
    • @SergeyA 我虽然问题是关于来电者方面的,但我确实误读了。但是没有办法知道 const 指针或引用是否从内部引用了实际的 const 对象......
    • @Quentin,我相信,这就是 OP 所要求的。
    • @guivenca 您需要为此使用std::remove_pointer_t&lt;decltype(param)&gt;:指针不是const,它的指针是const
    猜你喜欢
    • 2013-07-19
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 2018-09-09
    相关资源
    最近更新 更多