Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #15117 > unrolled thread
| Started by | Qi <no@no.no> |
|---|---|
| First post | 2012-04-01 10:05 +0800 |
| Last post | 2012-04-02 14:41 +0000 |
| Articles | 17 — 7 participants |
Back to article view | Back to comp.lang.c++
Any way to defer template function overloading? Qi <no@no.no> - 2012-04-01 10:05 +0800
Re: Any way to defer template function overloading? Ian Collins <ian-news@hotmail.com> - 2012-04-01 16:06 +1200
Re: Any way to defer template function overloading? Qi <no@no.no> - 2012-04-01 13:53 +0800
Re: Any way to defer template function overloading? Juha Nieminen <nospam@thanks.invalid> - 2012-04-01 17:24 +0000
Re: Any way to defer template function overloading? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2012-04-02 00:40 +0200
Re: Any way to defer template function overloading? Ian Collins <ian-news@hotmail.com> - 2012-04-02 11:02 +1200
Re: Any way to defer template function overloading? Juha Nieminen <nospam@thanks.invalid> - 2012-04-02 05:29 +0000
Re: Any way to defer template function overloading? Qi <no@no.com> - 2012-04-02 13:48 +0800
Re: Any way to defer template function overloading? Ian Collins <ian-news@hotmail.com> - 2012-04-02 17:53 +1200
Re: Any way to defer template function overloading? Qi <no@no.com> - 2012-04-02 13:57 +0800
Re: Any way to defer template function overloading? Ian Collins <ian-news@hotmail.com> - 2012-04-02 18:12 +1200
Re: Any way to defer template function overloading? Miles Bader <miles@gnu.org> - 2012-04-02 15:32 +0900
Re: Any way to defer template function overloading? Miles Bader <miles@gnu.org> - 2012-04-02 14:58 +0900
Re: Any way to defer template function overloading? Juha Nieminen <nospam@thanks.invalid> - 2012-04-02 10:11 +0000
Re: Any way to defer template function overloading? Qi <no@no.com> - 2012-04-02 19:04 +0800
Re: Any way to defer template function overloading? Qi <no@no.com> - 2012-04-02 19:17 +0800
Re: Any way to defer template function overloading? jgk@panix.com (Joe keane) - 2012-04-02 14:41 +0000
| From | Qi <no@no.no> |
|---|---|
| Date | 2012-04-01 10:05 +0800 |
| Subject | Any way to defer template function overloading? |
| Message-ID | <jl8d4h$hbf$1@speranza.aioe.org> |
Let me show some test code.
=====code start
template <typename T>
void abc(const T &)
{
cout << "1" << endl;
}
template <typename T>
void test(const T & a)
{
abc(a);
}
void abc(const string &)
{
cout << "2" << endl;
}
int main(int argc, char * argv[])
{
(void)argc;
(void)argv;
string s;
test(s);
return 0;
}
=====code end
"abc" is a template function that I use as some kind of traits.
(similar as get_pointer in Boost).
The "string" overloading is after the "test" function.
"test" is the function where using "abc". "test" is a template
function too.
"main" is the function that using "test". It's guaranteed that
all overloading will be declared before main (but may after "test").
In standard way, above code will print "1" on GCC (VC will print "2"
because of its less standard template parsing).
My question is, is there any way to make "test" chooses
the "string" overloading and print 2, no matter the overloading
is before or after "test"?
The reason I want that is, the overloading functions may spread
in multiple headers, if "test" can only choose the overloading
that declared before it, that will enforce the including order of
the headers.
Thanks
--
WQ
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-04-01 16:06 +1200 |
| Message-ID | <9tq2ijFm3gU1@mid.individual.net> |
| In reply to | #15117 |
On 04/ 1/12 02:05 PM, Qi wrote:
> Let me show some test code.
>
> =====code start
>
> template<typename T>
> void abc(const T&)
> {
> cout<< "1"<< endl;
> }
>
> template<typename T>
> void test(const T& a)
> {
> abc(a);
> }
>
> void abc(const string&)
> {
> cout<< "2"<< endl;
> }
>
> int main(int argc, char * argv[])
> {
> (void)argc;
> (void)argv;
Why do this?
> string s;
> test(s);
>
> return 0;
> }
>
> =====code end
>
> "abc" is a template function that I use as some kind of traits.
> (similar as get_pointer in Boost).
> The "string" overloading is after the "test" function.
>
> "test" is the function where using "abc". "test" is a template
> function too.
>
> "main" is the function that using "test". It's guaranteed that
> all overloading will be declared before main (but may after "test").
>
> In standard way, above code will print "1" on GCC (VC will print "2"
> because of its less standard template parsing).
>
> My question is, is there any way to make "test" chooses
> the "string" overloading and print 2, no matter the overloading
> is before or after "test"?
Make the function a specialisation:
template <>
void abc(const std::string&)
{
std::cout << "2" << std::endl;
}
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Qi <no@no.no> |
|---|---|
| Date | 2012-04-01 13:53 +0800 |
| Message-ID | <jl8qgf$6bf$1@speranza.aioe.org> |
| In reply to | #15118 |
On 2012-4-1 12:06, Ian Collins wrote:
>
> Make the function a specialisation:
>
> template <>
> void abc(const std::string&)
> {
> std::cout << "2" << std::endl;
> }
Awesome, it works perfectly. Thanks.
Can I understand that as, the specialization is solved
at the second pass of template parsing, while the overloading
is solved at the first pass?
However, here has some discussion on the risk to use
template function specialization
http://www.gotw.ca/publications/mill17.htm
Seems the class specialization way is better and safer. :-)
--
WQ
[toc] | [prev] | [next] | [standalone]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2012-04-01 17:24 +0000 |
| Message-ID | <4f788f56$0$4347$7b1e8fa0@news.nbl.fi> |
| In reply to | #15117 |
Qi <no@no.no> wrote:
> int main(int argc, char * argv[])
> {
> (void)argc;
> (void)argv;
This seemed like nonsensical code because it does nothing. Then I realized
that it's an ugly hack to silence the compiler warning about unused
variables. That's not how you do it.
The proper way of getting rid of the warnings is to not name the
parameters. If you still want to have their names visible, you can
simply comment them out:
int main(int /*argc, char** /*argv*/)
{
...
}
Incidentally, main() doesn't need parameters, so you can just omit them:
int main()
{
...
}
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2012-04-02 00:40 +0200 |
| Message-ID | <jlalgo$376$1@dont-email.me> |
| In reply to | #15121 |
On 01.04.2012 19:24, Juha Nieminen wrote:
> Qi<no@no.no> wrote:
>> int main(int argc, char * argv[])
>> {
>> (void)argc;
>> (void)argv;
>
> This seemed like nonsensical code because it does nothing. Then I realized
> that it's an ugly hack to silence the compiler warning about unused
> variables. That's not how you do it.
Right. I used to advocate a function template for that. But now I'd
rather use a macro, e.g. like this:
<code>
#if !defined( CPP_DECLARE_UNUSED )
# define CPP_DECLARE_UNUSED( argName ) \
(void)(argName, void(), 0); struct argName; (void)0
#endif
// SO user sehe: "(void)0" for semicolon
// SO user R. Martinho Fernandes, pointed out operator void() problem
// SO user Johannes Schaub, solution to operator,() problem
</code>
> The proper way of getting rid of the warnings is to not name the
> parameters. If you still want to have their names visible, you can
> simply comment them out:
>
> int main(int /*argc, char** /*argv*/)
But the names have documentary value, and those comments do not nest,
e.g. for the purpose of commenting out code.
> {
> ...
> }
>
> Incidentally, main() doesn't need parameters, so you can just omit them:
>
> int main()
> {
> ...
> }
Yes. :-)
Cheers,
- Alf
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-04-02 11:02 +1200 |
| Message-ID | <9ts545FfaaU2@mid.individual.net> |
| In reply to | #15122 |
On 04/ 2/12 10:40 AM, Alf P. Steinbach wrote:
> On 01.04.2012 19:24, Juha Nieminen wrote:
>> Qi<no@no.no> wrote:
>>> int main(int argc, char * argv[])
>>> {
>>> (void)argc;
>>> (void)argv;
>>
>> This seemed like nonsensical code because it does nothing. Then I realized
>> that it's an ugly hack to silence the compiler warning about unused
>> variables. That's not how you do it.
>
> Right. I used to advocate a function template for that. But now I'd
> rather use a macro, e.g. like this:
>
>
> <code>
> #if !defined( CPP_DECLARE_UNUSED )
> # define CPP_DECLARE_UNUSED( argName ) \
> (void)(argName, void(), 0); struct argName; (void)0
> #endif
> // SO user sehe: "(void)0" for semicolon
> // SO user R. Martinho Fernandes, pointed out operator void() problem
> // SO user Johannes Schaub, solution to operator,() problem
> </code>
>
>
>> The proper way of getting rid of the warnings is to not name the
>> parameters. If you still want to have their names visible, you can
>> simply comment them out:
>>
>> int main(int /*argc, char** /*argv*/)
>
> But the names have documentary value, and those comments do not nest,
> e.g. for the purpose of commenting out code.
So include the names in the function declaration, but not in the definition.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2012-04-02 05:29 +0000 |
| Message-ID | <4f79393e$0$4376$7b1e8fa0@news.nbl.fi> |
| In reply to | #15122 |
Alf P. Steinbach <alf.p.steinbach+usenet@gmail.com> wrote: > <code> > #if !defined( CPP_DECLARE_UNUSED ) > # define CPP_DECLARE_UNUSED( argName ) \ > (void)(argName, void(), 0); struct argName; (void)0 > #endif > // SO user sehe: "(void)0" for semicolon > // SO user R. Martinho Fernandes, pointed out operator void() problem > // SO user Johannes Schaub, solution to operator,() problem > </code> That seems worse than just having the compiler warning.
[toc] | [prev] | [next] | [standalone]
| From | Qi <no@no.com> |
|---|---|
| Date | 2012-04-02 13:48 +0800 |
| Message-ID | <jlbekq$693$1@speranza.aioe.org> |
| In reply to | #15121 |
On 2012-4-2 1:24, Juha Nieminen wrote:
> Qi<no@no.no> wrote:
>> int main(int argc, char * argv[])
>> {
>> (void)argc;
>> (void)argv;
>
> This seemed like nonsensical code because it does nothing. Then I realized
> that it's an ugly hack to silence the compiler warning about unused
> variables. That's not how you do it.
Ugly? Maybe.
But it makes a lot of sense to me.
There is time that some parameters are not used. Such as implementing
an interface, and the interface function just has extra parameters for
flexibility.
Though I can write "int main(int, char **)", I won't do it because
I expect others may read my code and feel difficult to understand
the function without the parameter name.
For example,
int findSomeThing(int, int); // what's that? Don't know
int findSomeThing(int beginIndex, int endIndex); // oh, find between
// beginIndex, endIndex, but the function doesn't use them.
Of course we can put the parameter name to declaration and omit
in the definition, but then the reader needs to dig into the header
only for parameters when he is reading the source code.
int main(int /*argc*/, char** /*argv*/) ?
To me, it's more ugly and easier to misread than (void)argc.
**? */? How may * and / there in one line?
And I think "(void)argc" is well known for C++ developers, maybe
I'm wrong?
--
WQ
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-04-02 17:53 +1200 |
| Message-ID | <9tst77FfaaU3@mid.individual.net> |
| In reply to | #15125 |
On 04/ 2/12 05:48 PM, Qi wrote:
> On 2012-4-2 1:24, Juha Nieminen wrote:
>> Qi<no@no.no> wrote:
>>> int main(int argc, char * argv[])
>>> {
>>> (void)argc;
>>> (void)argv;
>>
>> This seemed like nonsensical code because it does nothing. Then I realized
>> that it's an ugly hack to silence the compiler warning about unused
>> variables. That's not how you do it.
>
> Ugly? Maybe.
> But it makes a lot of sense to me.
>
> There is time that some parameters are not used. Such as implementing
> an interface, and the interface function just has extra parameters for
> flexibility.
>
> Though I can write "int main(int, char **)", I won't do it because
> I expect others may read my code and feel difficult to understand
> the function without the parameter name.
Then why don't you just write "int main()"?
> For example,
> int findSomeThing(int, int); // what's that? Don't know
> int findSomeThing(int beginIndex, int endIndex); // oh, find between
> // beginIndex, endIndex, but the function doesn't use them.
>
> Of course we can put the parameter name to declaration and omit
> in the definition, but then the reader needs to dig into the header
> only for parameters when he is reading the source code.
If the parameter isn't used (and named), why would the reader look for it?
> int main(int /*argc*/, char** /*argv*/) ?
> To me, it's more ugly and easier to misread than (void)argc.
> **? */? How may * and / there in one line?
>
> And I think "(void)argc" is well known for C++ developers, maybe
> I'm wrong?
Maybe, most people I know simply omit the name.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Qi <no@no.com> |
|---|---|
| Date | 2012-04-02 13:57 +0800 |
| Message-ID | <jlbf5d$8ae$1@speranza.aioe.org> |
| In reply to | #15126 |
On 2012-4-2 13:53, Ian Collins wrote: > > Then why don't you just write "int main()"? "main" function is only the one in my sample code. I have a lot of functions that can't omit the parameters completely... > If the parameter isn't used (and named), why would the reader look for it? Because the parameter name can help readability and help to understand the function, IMHO. -- WQ
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-04-02 18:12 +1200 |
| Message-ID | <9tsu9hFfaaU4@mid.individual.net> |
| In reply to | #15127 |
On 04/ 2/12 05:57 PM, Qi wrote: > On 2012-4-2 13:53, Ian Collins wrote: >> >> Then why don't you just write "int main()"? > > "main" function is only the one in my sample code. > I have a lot of functions that can't omit the parameters > completely... > >> If the parameter isn't used (and named), why would the reader look for it? > > Because the parameter name can help readability and help to > understand the function, IMHO. Surly the argument about how to comment out the name is evidence that simply omitting the name is the best documentation for a parameter that isn't used? I've yet to see a case where clutter helps readability. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Miles Bader <miles@gnu.org> |
|---|---|
| Date | 2012-04-02 15:32 +0900 |
| Message-ID | <87bona8x02.fsf@catnip.gol.com> |
| In reply to | #15129 |
Ian Collins <ian-news@hotmail.com> writes: >> Because the parameter name can help readability and help to >> understand the function, IMHO. > > Surly the argument about how to comment out the name is evidence that > simply omitting the name is the best documentation for a parameter > that isn't used? I've yet to see a case where clutter helps > readability. I think it depends. For instance, consider the initial (highest-level) definition of a virtual method. You want the parameter names because they're acting as documentation for the interface (and the method comment probably refers to them by name). But I've found that I often use an inline method body with a trivial "default definition" that doesn't reference any of the parameters (and just returns false or something). I don't want to use an out-of-line method definition for that method (it's just annoying, and the inline definition actually provides good documentation of such a trivial default), but the compiler complains because I don't reference any of the arguments[*], although obviously the arguments may be referenced by overrides. What I usually do is just comment out parameter names. [*] I actually submitted a bug report trying to make an argument that g++ shouldn't warn about unreferenced arguments in inline definitions of virtual methods, but didn't get much sympathy.... -miles -- Omochiroi!
[toc] | [prev] | [next] | [standalone]
| From | Miles Bader <miles@gnu.org> |
|---|---|
| Date | 2012-04-02 14:58 +0900 |
| Message-ID | <87mx6u8ykw.fsf@catnip.gol.com> |
| In reply to | #15125 |
Qi <no@no.com> writes: > And I think "(void)argc" is well known for C++ developers, maybe > I'm wrong? I've never seen it used before. OTOH, it's reasonably obvious what it does (to me at least).... Whether it's more or less ugly than just commenting out the parameter names, e.g. "int /*argc*/, char **/*argv*/" is a matter of opinion I suppose... -Miles -- o The existentialist, not having a pillow, goes everywhere with the book by Sullivan, _I am going to spit on your graves_.
[toc] | [prev] | [next] | [standalone]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2012-04-02 10:11 +0000 |
| Message-ID | <4f797b49$0$2798$7b1e8fa0@news.nbl.fi> |
| In reply to | #15125 |
Qi <no@no.com> wrote: > Though I can write "int main(int, char **)", I won't do it because > I expect others may read my code and feel difficult to understand > the function without the parameter name. So instead you put no-op lines of code that are even more confusing, and which exist solely as a hack to get rid of some compiler warnings? > Of course we can put the parameter name to declaration and omit > in the definition, but then the reader needs to dig into the header > only for parameters when he is reading the source code. Exactly how does knowing the parameter's name help understanding the implementation of the function, which does not use said name? "Hey, I can't understand this function implementation because one of the unused parameters is not named. It confuses me. I have no idea what this implementation, which doesn't use that parameter, is doing." > And I think "(void)argc" is well known for C++ developers, maybe > I'm wrong? I have been programming with C++ for over 15 years, most of that time professionally. I have never seen that hack used before.
[toc] | [prev] | [next] | [standalone]
| From | Qi <no@no.com> |
|---|---|
| Date | 2012-04-02 19:04 +0800 |
| Message-ID | <jlc13h$kjj$1@speranza.aioe.org> |
| In reply to | #15131 |
On 2012-4-2 18:11, Juha Nieminen wrote: >> And I think "(void)argc" is well known for C++ developers, maybe >> I'm wrong? > > I have been programming with C++ for over 15 years, most of that > time professionally. I have never seen that hack used before. Hmmm. Maybe I was wrong. If "(void)argc" is not well known, I will definitely not use it any longer. Indeed when I first read "(void)argc" before I knew it, I needed to think a moment about what it does... Thanks for pointing that out. -- WQ
[toc] | [prev] | [next] | [standalone]
| From | Qi <no@no.com> |
|---|---|
| Date | 2012-04-02 19:17 +0800 |
| Message-ID | <jlc1tj$kjj$3@speranza.aioe.org> |
| In reply to | #15132 |
Hi all, Thanks for let me know my that potential mistake. I started another thread. Please post there for this topic. It's too off topic in this thread. :-) -- WQ
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-04-02 14:41 +0000 |
| Message-ID | <jlcdqt$ltg$1@reader1.panix.com> |
| In reply to | #15117 |
In article <jl8d4h$hbf$1@speranza.aioe.org>, Qi <no@no.no> wrote:
>int main(int argc, char * argv[])
>{
> (void)argc;
> (void)argv;
>
> string s;
> test(s);
>
> return 0;
>}
That is an old C idiom, and there's nothing wrong with it.
Saying 'comment out the parameter' misses the point.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web