Force function called only with certain types
I was looking at security when using char * for bool in C ++ 11 and it has been suggested that if you do
template<typename T>
void foo(T) = delete;
void foo(int f) {}
Something that foo
will only work with an explicit argument given int
. I made a test case:
template<typename T>
void foo(T) = delete;
void foo(int f) {}
int main()
{
foo(1);
foo(3.0);
foo(short(5));
foo(float(7.0));
foo(long(9));
}
I used coliru to compile the code from g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
( live example ) and I got the following errors:
main.cpp: In function 'int main()':
main.cpp:9:12: error: use of deleted function 'void foo(T) [with T = double]'
foo(3.0);
^
main.cpp:2:6: note: declared here
void foo(T) = delete;
^
main.cpp:10:17: error: use of deleted function 'void foo(T) [with T = short int]'
foo(short(5));
^
main.cpp:2:6: note: declared here
void foo(T) = delete;
^
main.cpp:11:19: error: use of deleted function 'void foo(T) [with T = float]'
foo(float(7.0));
^
main.cpp:2:6: note: declared here
void foo(T) = delete;
^
main.cpp:12:16: error: use of deleted function 'void foo(T) [with T = long int]'
foo(long(9));
^
main.cpp:2:6: note: declared here
void foo(T) = delete;
^
compiling with clang also produced similar errors
Now that I was reading about = delete
on cppreference it stated
If the function is overloaded, the overload resolution occurs first, and the program is only ill-formed if the removed function is selected.
So if cppreference is correct and my program is poorly formed, does that mean it won't compile or undefined or undefined behavior?
source to share
Your program is poorly formed. First, for each call, foo
we perform overload resolution. This will cause:
foo(1); // foo(int )
foo(3.0); // foo<T>, T=double
foo(short(5)); // foo<T>, T=short
foo(float(7.0)); // foo<T>, T=float
foo(long(9)); // foo<T>, T=long
Four of these functions are explicitly deleted
and from [dcl.fct.def.delete]:
A program that refers to a remote function implicitly or explicitly other than a declaration is ill-formed.
This is not undefined or unspecified behavior. It should just not compile.
source to share