问题
I have seen example code like this before
class C
{
C();
~C();
foo(T1, T2);
}
C::foo(T1, T2)
{
//not using T1/T2
}
versus conventional code like this
class D
{
D();
~D();
bar(T1 t1, T2 t2);
}
D::bar(T1 t1, T2 t2)
{
//using t1 and t2
}
And I am wondering what is the purpose of not defining your type variables for usability? Do most people do this just to hint that those parameters of the api are not currently in use, but to ensure backward compatibility in the future?
Is it possibly for RTTI, or referencing static variables (although the various samples I've seen were not using it for this purpose, they werent even templated functions, the variables were simply unused). I've tried searching for this feature but I am not even sure what it is called or what to search.
Basically, what are the reasons/benefits/downsides for using this approach?
回答1:
This is commonly done to suppress compiler warnings about unused variables. When you do not create a variable name, the compiler will not warn you that the variable is not being used in the function.
Like you stated, its usually that parameters are not being used for the particular implementation:
class an_iface
{
public:
an_iface();
virtual int doSomething(int valNeeded)=0;
}
#define NOT_SUPPORTED -1
class something : public an_iface
{
public:
something();
int doSomething (int) { return NOT_SUPPORTED; }
}
class somethingMore : public an_iface
{
public:
somethingMore();
int doSomething(int stuff) { return stuff * 10; }
}
回答2:
Apart from what @dag has mentioned, a function definition without parameter name finds its usage in template specialization. I know you have mentioned that there are no templates in the example you have posted, but for sake of completeness i'd like to post this use case:
Suppose you have defined an erase function for std containers. But you want different erase_helper to do the actual work based on the container type. A common and acceptable practice is to use traits.
// Tags for containers
struct vector_tag {};
struct map_tag {};
// Trait class
template <typename C> struct container_traits;
// Specialization of trait class
template <typename T, typename A>
struct container_traits<std::vector<T, A>>
{
typedef vector_tag category;
};
template <typename K, typename V, typename C, typename A>
struct container_traits<std::map<K, V, C, A>>
{
typedef map_tag category;
};
// Helper function
template <typename Container, typename X>
void erase_helper(Container& c, const X& x, vector_tag) // <-- no param name
{
// Erase element from vector
}
template <typename Container, typename X>
void erase_helper(Container& c, const X& x, map_tag) // <-- no param name
{
// Erase element from map
}
// Function interface
template <typename Container, typename X>
void erase(Container& c, const X& x)
{
erase_helper(c, x, typename container_traits<Container>::category());
}
You can see here, erase_helper has third parameter without a name. Type of parameter tells compiler to pick correct function at template instantiation phase.
回答3:
Parameters are designed before the implements in more cases which affected by the architecture more directly
Parameters may be unused because:
- Overload a virtual function which has more parameters than needed in derived class
- Parameters exist for history reason, and don't want to change the api yet
- Consider for the need of the future
来源:https://stackoverflow.com/questions/10494056/specifying-function-parameter-type-but-not-variable