在调用函数时阻止int的转换

时间:2016-12-20 07:48:10

标签: c++ c++11 casting

我有以下代码:

<script>
    function formSubmit(){
        var name = document.getElementById("name").value;
        var message = document.getElementById("message").value;
        var dataString = 'name='+ name + '&message=' + message;
        jQuery.ajax({
            url: "submit.php",
            data: dataString,
            type: "POST",
            success: function(data){
                $("#myForm").html(data);
            },
            error: function (){}
        });
    return true;
    }
</script>

当我尝试编译时,它会出现无法将void foo(int64_t x) {} void bar(int64_t* x) {} int main() { int32_t a = 3; foo(a); bar(&a); } 转换为int32_t*的错误, 这就是我想要的。

当我尝试调用int64_t*时,是否可能出现类似的错误?

3 个答案:

答案 0 :(得分:7)

作为一种解决方法,您可以使用已删除的版本重载 foo

void foo(int32_t x) = delete;
void foo(int64_t x) {}

作为一种更通用的解决方案,您可以创建一个已删除的函数模板,然后将其专门用于 int64_t (感谢@Someprogrammerdude):

template<typename T>
void foo(T) = delete;

template<>
void foo(int64_t x) {}

有趣的是,它不会使用clang 3.8进行编译,但可以使用clang 3.9gcc 6.2进行编译。

答案 1 :(得分:3)

您可以使用模板和static_assert

template<typename T>
void foo(T x) {
    static_assert(std::is_same<int64_t, T>::value, "!");
    // ...
}

或完全专业化,其中主要模板未定义或被删除:

template<typename>
void foo(T);

// This should be fine as well
//
// template<typename>
// void foo(T) = delete;

template<>
void foo(int64_t x) {
    // ...
}

答案 2 :(得分:1)

如果您将签名更改为

void foo(int64_t& x)

然后,因为int32_t无法绑定const的非int64_t引用,编译将失败。

但是这种技术受制于现在foo 可以修改通过引用传递给它的变量。当然你可以在foo本身控制它,但总的来说它对我来说似乎不是一个好主意。

另请注意,它无法绑定到即使是正确类型的匿名临时文件,例如foo((int64_t)1);