There is a situation where I want to collect all the nodes names of a path to one key in JSON. Consider the condition: JSON array index "0", "1" are also allowed, but it is easy to forget the quotes, which would lead to a crash when doing dereference. So I want compiler to reject this kind of parameters. Example:
#include <vector>
#include <iostream>
int func(const std::vector<const char*>& pin) {
return pin.size();
}
int main() {
// {"aname", "3", "path", "0"} wanted but this still compile
std::cout << func({"aname", "3", "path", 0}) << std::endl;
}
Refering to How do I avoid implicit conversions on non-constructing functions? I tried something as following:
#include <vector>
#include <iostream>
// I want to describe only char pointer parameter is allowed as element,
// parameter of any integer types should be rejected.
int func(const std::vector<const char*>& pin) {
return pin.size();
}
int func(const std::vector<int>& pin) = delete;
// or
template<typename T>
int func(const std::vector<T>& pin) = delete;
int main() {
std::cout << func({"aname", "3", "path", 0}) << std::endl;
}
But the compiler still can not understand me.
Any suggestion?
Please point out any misuse of terminologies and assumptions, thank you!
Implicit numeric conversions Any integral numeric type is implicitly convertible to any floating-point numeric type.
Implicit conversions allow the compiler to treat values of a type as values of another type. There's at least one set of scenarios in which this is unambiguously bad: non-total conversions. That is, converting an A to a B when there exists A s for which this conversion is impossible.
Overview. Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.
Implicit type conversion also known as automatic type conversion is carried out by the compiler without the need for a user-initiated action. It takes place when an expression of more than one data type is present which in such an instance type conversion takes place to avoid data loss.
Something like this? It's very similar to the overload solution you suggested, but requires wrapping the vector type. Fails to build if you provide a literal 0
because the deleted constructor overload is chosen.
#include <memory>
#include <new>
#include <vector>
#include <iostream>
using std::vector;
template<typename T>
struct no_zero {
no_zero(T val) : val(val) {}
no_zero(int val) = delete;
operator T() { return val; }
T val;
};
int func(const vector<no_zero<const char*> >& pin) {
return pin.size();
}
int main() {
// {"aname", "3", "path", "0"} wanted but this still compile
std::cout << func({"aname", "3", "path", 0}) << std::endl;
}
I like Mikel Rychliski's answer. However there already exists a solution in Guideline Support Library:
gsl::not_null
I highly recommend GSL. It's created and backed by many C++ experts, Bjarne Stroustrup himself and Herb Sutter among them. And the C++ Core Guidelines are actively being integrated into the compiler warnings and static analyzers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With