Tre*_*key 36 c++ casting function implicit-cast implicit-conversion
如何避免对非构造函数进行隐式转换?
我有一个函数,它接受一个整数作为参数,
但该函数也将采用字符,bools和long.
我相信它是通过隐式地施放它来实现的.
如何避免这种情况,以便函数只接受匹配类型的参数,否则将拒绝编译?
有一个关键字"显式"但它不适用于非构造函数.:\
我该怎么办?
以下程序编译,虽然我不喜欢:
#include <cstdlib>
//the function signature requires an int
void function(int i);
int main(){
int i{5};
function(i); //<- this is acceptable
char c{'a'};
function(c); //<- I would NOT like this to compile
return EXIT_SUCCESS;
}
void function(int i){return;}
Run Code Online (Sandbox Code Playgroud)
*请务必指出任何滥用术语和假设的行为
Pio*_*ycz 44
定义与所有其他类型匹配的函数模板:
void function(int); // this will be selected for int only
template <class T>
void function(T) = delete; // C++11
Run Code Online (Sandbox Code Playgroud)
这是因为始终首先考虑具有直接匹配的非模板函数.然后考虑具有直接匹配的函数模板 - 因此永远function<int>不会使用.但是对于其他任何东西,比如char,function<char>都会被使用 - 这会给你的编译错误:
void function(int) {}
template <class T>
void function(T) = delete; // C++11
int main() {
function(1);
function(char(1)); // line 12
}
Run Code Online (Sandbox Code Playgroud)
错误:
prog.cpp: In function 'int main()':
prog.cpp:4:6: error: deleted function 'void function(T) [with T = char]'
prog.cpp:12:20: error: used here
Run Code Online (Sandbox Code Playgroud)
这是C++ 03方式:
// because this ugly code will give you compilation error for all other types
class DeleteOverload
{
private:
DeleteOverload(void*);
};
template <class T>
void function(T a, DeleteOverload = 0);
void function(int a)
{}
Run Code Online (Sandbox Code Playgroud)
Luc*_*ore 20
你不能直接,因为一个char自动升级到int.
您可以采用一种技巧:创建一个带有charas参数但不实现它的函数.它会编译,但你会得到一个链接器错误:
void function(int i)
{
}
void function(char i);
//or, in C++11
void function(char i) = delete;
Run Code Online (Sandbox Code Playgroud)
使用char参数调用函数将破坏构建.
术语:非构造函数?你的意思是一个不是构造函数的函数吗?
Hun*_*ler 10
如果您不介意模板函数(您可能会介意),最现代的解决方案是使用带有std::enable_if和的模板化函数std::is_same。
即:
// Where we want to only take int
template <class T, std::enable_if_t<std::is_same<T,int>,bool> = false>
void func(T x) {
}
Run Code Online (Sandbox Code Playgroud)
我最近切换到 c++20,我相信有更好的方法。如果您的团队或者您不使用 c++20,或者不熟悉新概念库,请不要使用它。这更好,并且是新的 c++20 标准中概述的预期方法,以及新功能的作者(阅读 Bjarne Stroustrup在这里撰写的论文。
template <class T>
requires std::same_as(T,int)
void func(T x) {
//...
}
Run Code Online (Sandbox Code Playgroud)
下面是一个更好的方法,因为它解释了你的原因,有一个显式的 int。如果你经常这样做,并且想要一个好的模式,我会做以下事情:
template <class T>
concept explicit_int = std::same_as<T,int>;
template <explicit_int T>
void func(T x) {
}
Run Code Online (Sandbox Code Playgroud)
还有一种实现这种可能性的方法:
template <class T>
concept explicit_int = std::same_as<T,int>;
void func(explicit_int auto x) {
}
Run Code Online (Sandbox Code Playgroud)
这是一个通用的解决方案,如果function使用除int之外的任何东西调用,则会在编译时导致错误
template <typename T>
struct is_int { static const bool value = false; };
template <>
struct is_int<int> { static const bool value = true; };
template <typename T>
void function(T i) {
static_assert(is_int<T>::value, "argument is not int");
return;
}
int main() {
int i = 5;
char c = 'a';
function(i);
//function(c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它的工作原理是允许参数的任何类型起作用,但is_int用作类型级谓词.泛型实现is_int具有false值,但int类型的显式特化值为true,因此静态断言保证参数具有完全类型,int否则存在编译错误.
| 归档时间: |
|
| 查看次数: |
14720 次 |
| 最近记录: |