A couple template related questions:
1. In the code pasted below, why does the basic version get selected in
the call to foo and the const version get selected in the call to bar?
2. When working with STL output iterators, is there any general advice
on whether they should be passed by value or reference? I have
templated code which takes ostream_iterators or back_insert_iterators
which I inititally chose to pass by reference, but I've run into the
situation analogous to below where I have to duplicate my code to handle
const and non-const references to each iterator type (4 basically
identical implementations there).
3. Related to this, for my code which can take either an
ostream_iterator or a back_insert_iterator, is there any way to tell the
compiler that these two should be treated identically. Each is a model
of Output Iterator, but I can't find any way to express this in the
language. (Note, the code may also take a Back Insertion Sequence so I
can't simply have the template code assume it's argument is an Output
Iterator.)
Regarding 3, I think may best approach may be to use different function
names for the Output Iterator version and the Back Insertion Sequence
version, and let the template assume one of these models.
Thanks for your advice,
Mark
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
void foo (T& t) {cout << "basic version\n";}
template <typename T>
void foo (const vector<T>& t) {cout << "const version\n";}
template <typename T>
void bar (T t) {cout << "basic version\n";}
template <typename T>
void bar (const vector<T>& t) {cout << "const version\n";}
int main ()
{
vector<int> vi;
foo(vi); // output: basic version
bar(vi); // output: const version
} 12 1620
"Mark P" <us****@fall2005REMOVE.fastmailCAPS.fm> wrote in message
news:LN*****************@newssvr27.news.prodigy.ne t...
| A couple template related questions:
|
| 1. In the code pasted below, why does the basic version get selected
in
| the call to foo and the const version get selected in the call to bar?
The compiler is free to choose whether it will call the vector template
or the int template since you did not specify which foo< ? >() template
to use in main(). In the case of foo(), it probably found the vector
template to be more efficient and in the case of bar() it probably
calculated that passing the vector via copy considerably less efficient.
Hence the output you got.
note... missing reference... T& t
template <typename T>
void bar (T t) {cout << "copy vector template\n";}
Get it? You aren't dealing with a basic vs const template fight.
Besides, basic vs const fights don't exist. A programmer needs to tell
the compiler whether its const or not. Otherwise the compiler will
likely generate a diagnostic where it can't decide which template
generation is more efficient or appropriate (in the case you supply both
a const and a non-const version).
#include <iostream>
#include <vector>
template <typename T>
void foo (T& t)
{
std::cout << "foo(), vector template\n";
}
template <typename T>
void foo (const std::vector<T>& t)
{
std::cout << "foo(), int template\n";
}
template <typename T>
void bar (T t)
{
std::cout << "bar(), copy vector template\n";
}
template <typename T>
void bar (const std::vector<T>& t)
{
std::cout << "bar(), int template\n";
}
int main ()
{
std::vector<int> vi;
foo< std::vector< int > >(vi);
foo< int >(vi);
bar< std::vector< int > >(vi);
bar< int >(vi);
return 0;
}
/*
foo(), vector template
foo(), int template
bar(), copy vector template
bar(), int template
*/
<snip>
Peter_Julian wrote: "Mark P" <us****@fall2005REMOVE.fastmailCAPS.fm> wrote in message news:LN*****************@newssvr27.news.prodigy.ne t... | A couple template related questions: | | 1. In the code pasted below, why does the basic version get selected in | the call to foo and the const version get selected in the call to bar?
The compiler is free to choose whether it will call the vector template or the int template since you did not specify which foo< ? >() template to use in main(). In the case of foo(), it probably found the vector template to be more efficient and in the case of bar() it probably calculated that passing the vector via copy considerably less efficient. Hence the output you got.
note... missing reference... T& t template <typename T> void bar (T t) {cout << "copy vector template\n";}
Get it?
I'm not sure I do. Surely there are rules which give one template of a
function priority over another, otherwise what's the point in
specialization at all? Are you saying that those rules are unable to
distinguish between the two choices in each case and it's arbitrary that
the compiler opts for one over another since I didn't explicitly specify
the template arguments?
- Mark
You aren't dealing with a basic vs const template fight. Besides, basic vs const fights don't exist. A programmer needs to tell the compiler whether its const or not. Otherwise the compiler will likely generate a diagnostic where it can't decide which template generation is more efficient or appropriate (in the case you supply both a const and a non-const version).
#include <iostream> #include <vector>
template <typename T> void foo (T& t) { std::cout << "foo(), vector template\n"; }
template <typename T> void foo (const std::vector<T>& t) { std::cout << "foo(), int template\n"; }
template <typename T> void bar (T t) { std::cout << "bar(), copy vector template\n"; }
template <typename T> void bar (const std::vector<T>& t) { std::cout << "bar(), int template\n"; }
int main () { std::vector<int> vi;
foo< std::vector< int > >(vi); foo< int >(vi); bar< std::vector< int > >(vi); bar< int >(vi);
return 0; }
/* foo(), vector template foo(), int template bar(), copy vector template bar(), int template */
<snip>
Mark P wrote: 2. When working with STL output iterators, is there any general advice on whether they should be passed by value or reference?
They should be cheap to copy, therefore by value.
3. Related to this, for my code which can take either an ostream_iterator or a back_insert_iterator, is there any way to tell the compiler that these two should be treated identically.
Those are not iterator categories. 'input iterator' or 'bidirectional
iterator' are such categories....
Each is a model of Output Iterator, but I can't find any way to express this in the language.
....which you seem aware of. Now, typically, you don't express the iterator
type other than by the way you use it in a function. Other than that, you
only use
template<typename InIterator>
void print( InIterator beg, InIterator end)
{ ... }
i.e. maybe chose the name so it conveys that it is an input iterator but
otherwise leave the the iterator type as a template argument.
Regarding 3, I think may best approach may be to use different function names for the Output Iterator version and the Back Insertion Sequence version, and let the template assume one of these models.
I'm not sure, why not use overloading? Why not use a template function?
Maybe if you provided an example you could get better advise.
Uli
--
FAQ: http://ma.rtij.nl/acllc-c++.FAQ.html
Mark P wrote: Peter_Julian wrote: "Mark P" <us****@fall2005REMOVE.fastmailCAPS.fm> wrote in message news:LN*****************@newssvr27.news.prodigy.ne t... | A couple template related questions: | | 1. In the code pasted below, why does the basic version get selected in | the call to foo and the const version get selected in the call to bar?
The compiler is free to choose whether it will call the vector template or the int template since you did not specify which foo< ? >() template to use in main(). In the case of foo(), it probably found the vector template to be more efficient and in the case of bar() it probably calculated that passing the vector via copy considerably less efficient. Hence the output you got.
No, the overload resolution is not influenced by the estimated code
effectivity.
note... missing reference... T& t template <typename T> void bar (T t) {cout << "copy vector template\n";}
Get it?
I'm not sure I do. Surely there are rules which give one template of a function priority over another, otherwise what's the point in specialization at all? Are you saying that those rules are unable to distinguish between the two choices in each case and it's arbitrary that the compiler opts for one over another since I didn't explicitly specify the template arguments?
There are rules. Compiler cannot choose anything arbitrarily.
That said, let's review your code.
template <typename T> void foo (T &);
template <typename T> void foo (const std::vector<T> &);
When you call 'foo(std::vector<int>&)', the templates get specialized
and are both added to the set of candidate functions. Normal overload
resolution is then performed on this set. The result is rather
straightforward and easily understandable:
// Following will be chosen
void foo (std::vector<int> &);
// This requires worse implicit conversion sequence than
// the first function and will not be called.
void foo (const std::vector<int> &);
When it comes to the 'bar' function, normal overload resolution will
fail, since neither function is better than the other.
// The call to 'bar(std::vector<int> &)' is ambigous.
void bar (std::vector<int>);
void bar (const std::vector<int> &);
Try that. Specialize the templates by hand. The code shouldn't compile.
When normal overload resolution fails and the candidate functions are
templates, a _partial function template ordering_ [14.5.5.2] comes to
play. In essence, the most specialized function template is chosen.
// The second function template is more specialised than the first
// and thus shall be selected by the overload resolution.
template <typename T> void bar (T);
template <typename T> void bar (const std::vector<T> &); #include <iostream> #include <vector>
template <typename T> void foo (T& t) { std::cout << "foo(), vector template\n"; }
template <typename T> void foo (const std::vector<T>& t) { std::cout << "foo(), int template\n"; }
template <typename T> void bar (T t) { std::cout << "bar(), copy vector template\n"; }
template <typename T> void bar (const std::vector<T>& t) { std::cout << "bar(), int template\n"; }
int main () { std::vector<int> vi;
foo< std::vector< int > >(vi); foo< int >(vi); bar< std::vector< int > >(vi); bar< int >(vi);
return 0; }
--
Martin
Peter_Julian wrote: "Mark P" <us****@fall2005REMOVE.fastmailCAPS.fm> wrote in message news:LN*****************@newssvr27.news.prodigy.ne t... | A couple template related questions: | | 1. In the code pasted below, why does the basic version get selected in | the call to foo and the const version get selected in the call to bar?
The compiler is free to choose whether it will call the vector template or the int template since you did not specify which foo< ? >() template to use in main(). In the case of foo(), it probably found the vector template to be more efficient and in the case of bar() it probably calculated that passing the vector via copy considerably less efficient. Hence the output you got.
Nononono......the compiler is NOT free to choose - and efficiency
certainly hasn't got anything to do with it.
Please do not give advice when you have no idea what you are talking
about.
/Peter
[snip]
/Peter
Peter_Julian wrote: "Mark P" <us****@fall2005REMOVE.fastmailCAPS.fm> wrote in message news:LN*****************@newssvr27.news.prodigy.ne t... | A couple template related questions: | | 1. In the code pasted below, why does the basic version get selected in | the call to foo and the const version get selected in the call to bar?
The compiler is free to choose whether it will call the vector template or the int template since you did not specify which foo< ? >() template to use in main(). In the case of foo(), it probably found the vector template to be more efficient and in the case of bar() it probably calculated that passing the vector via copy considerably less efficient. Hence the output you got.
note... missing reference... T& t template <typename T> void bar (T t) {cout << "copy vector template\n";}
Get it? You aren't dealing with a basic vs const template fight. Besides, basic vs const fights don't exist. A programmer needs to tell the compiler whether its const or not. Otherwise the compiler will likely generate a diagnostic where it can't decide which template generation is more efficient or appropriate (in the case you supply both a const and a non-const version).
#include <iostream> #include <vector>
template <typename T> void foo (T& t) { std::cout << "foo(), vector template\n"; }
template <typename T> void foo (const std::vector<T>& t) { std::cout << "foo(), int template\n"; }
template <typename T> void bar (T t) { std::cout << "bar(), copy vector template\n"; }
template <typename T> void bar (const std::vector<T>& t) { std::cout << "bar(), int template\n"; }
int main () { std::vector<int> vi;
foo< std::vector< int > >(vi); foo< int >(vi); bar< std::vector< int > >(vi); bar< int >(vi);
return 0; }
/* foo(), vector template foo(), int template bar(), copy vector template bar(), int template */
<snip>
Mark P wrote: A couple template related questions:
1. In the code pasted below, why does the basic version get selected in the call to foo and the const version get selected in the call to bar?
Because the only difference between the two foo templates is that one
of the foos has a constant parameter. The first template function is a
perfect match, whereas the second one requires a cast to const. The
best match is chosen.
For the bar-case, there is a plain bar and a bar that takes
std::vectors. The one taking vector is considered a better
specialisation even though there it requires a cast to const.
[snip]
/Peter Thanks for your advice, Mark
#include <iostream> #include <vector>
using namespace std;
template <typename T> void foo (T& t) {cout << "basic version\n";}
template <typename T> void foo (const vector<T>& t) {cout << "const version\n";}
template <typename T> void bar (T t) {cout << "basic version\n";}
template <typename T> void bar (const vector<T>& t) {cout << "const version\n";}
int main () { vector<int> vi; foo(vi); // output: basic version bar(vi); // output: const version }
In article <_8******************@newssvr29.news.prodigy.net >, Mark P
<us****@fall2005REMOVE.fastmailCAPS.fm> writes I'm not sure I do. Surely there are rules which give one template of a function priority over another, otherwise what's the point in specialization at all? Are you saying that those rules are unable to distinguish between the two choices in each case and it's arbitrary that the compiler opts for one over another since I didn't explicitly specify the template arguments?
It is certainly never arbitrary. As you say, there are rules though
learning them is sometimes a little complicated. However if the rules do
not result in a unique best choice, the compiler will issue and
ambiguity error and hand the problem back to you.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
Martin Vejnar wrote: Mark P wrote:
There are rules. Compiler cannot choose anything arbitrarily.
That said, let's review your code.
template <typename T> void foo (T &); template <typename T> void foo (const std::vector<T> &);
When you call 'foo(std::vector<int>&)', the templates get specialized and are both added to the set of candidate functions. Normal overload resolution is then performed on this set. The result is rather straightforward and easily understandable:
OK, so you've already hit upon a point of confusion for me.
When I write code like this:
vector<int> vi;
foo(vi);
The first sentence you wrote ("When you call...") suggests that I am
calling foo(vector<int>&) as opposed to foo(vector<int>), and as far as
I can tell this distinction ultimately accounts for the difference in
behavior observed below.
Is this how a compiler always interprets a function call? That is,
before any overload resolution and implicit conversion, are the
arguments of a function assumed to be references (to their static types)?
Thanks,
Mark // Following will be chosen void foo (std::vector<int> &);
// This requires worse implicit conversion sequence than // the first function and will not be called. void foo (const std::vector<int> &);
When it comes to the 'bar' function, normal overload resolution will fail, since neither function is better than the other.
// The call to 'bar(std::vector<int> &)' is ambigous. void bar (std::vector<int>); void bar (const std::vector<int> &);
Try that. Specialize the templates by hand. The code shouldn't compile.
When normal overload resolution fails and the candidate functions are templates, a _partial function template ordering_ [14.5.5.2] comes to play. In essence, the most specialized function template is chosen.
// The second function template is more specialised than the first // and thus shall be selected by the overload resolution. template <typename T> void bar (T); template <typename T> void bar (const std::vector<T> &);
#include <iostream> #include <vector>
template <typename T> void foo (T& t) { std::cout << "foo(), vector template\n"; }
template <typename T> void foo (const std::vector<T>& t) { std::cout << "foo(), int template\n"; }
template <typename T> void bar (T t) { std::cout << "bar(), copy vector template\n"; }
template <typename T> void bar (const std::vector<T>& t) { std::cout << "bar(), int template\n"; }
int main () { std::vector<int> vi;
foo< std::vector< int > >(vi); foo< int >(vi); bar< std::vector< int > >(vi); bar< int >(vi);
return 0; }
Mark P wrote: Martin Vejnar wrote: Mark P wrote:
There are rules. Compiler cannot choose anything arbitrarily.
That said, let's review your code.
template <typename T> void foo (T &); template <typename T> void foo (const std::vector<T> &);
When you call 'foo(std::vector<int>&)', the templates get specialized and are both added to the set of candidate functions. Normal overload resolution is then performed on this set. The result is rather straightforward and easily understandable:
OK, so you've already hit upon a point of confusion for me.
When I write code like this:
vector<int> vi; foo(vi);
The first sentence you wrote ("When you call...") suggests that I am calling foo(vector<int>&) as opposed to foo(vector<int>), and as far as I can tell this distinction ultimately accounts for the difference in behavior observed below.
Is this how a compiler always interprets a function call? That is, before any overload resolution and implicit conversion, are the arguments of a function assumed to be references (to their static types)?
Not really. I merely wanted to emphasise that 'vi' is an lvalue and can
be bound to a non-const reference (if it wasn't an lvalue, the first
'foo' would not participate in the resolution). Sorry for the confusion.
The actual rules used in overload resolution are rather complex. If you
want to get a deeper insight into this subject, you'll have no choice,
but to read through chapter [13.3] of the Standard. Or get a really good
book.
Following paragraph gives the reason for the result of an overload
resolution applied to the above code:
[13.3.3.2/3]
[...]
Standard conversion sequence S1 is a better conversion sequence
than standard conversion sequence S2 if
[...]
- S1 and S2 are reference bindings (8.5.3), and the types to which
the references refer are the same type except for top-level
cv-qualifiers, and the type to which the reference initialized by S2
refers is more cv-qualified than the type to which the reference
initialized by S1 refers. [...] // Following will be chosen void foo (std::vector<int> &);
// This requires worse implicit conversion sequence than // the first function and will not be called. void foo (const std::vector<int> &);
When it comes to the 'bar' function, normal overload resolution will fail, since neither function is better than the other.
// The call to 'bar(std::vector<int> &)' is ambigous. void bar (std::vector<int>); void bar (const std::vector<int> &);
Try that. Specialize the templates by hand. The code shouldn't compile.
When normal overload resolution fails and the candidate functions are templates, a _partial function template ordering_ [14.5.5.2] comes to play. In essence, the most specialized function template is chosen.
// The second function template is more specialised than the first // and thus shall be selected by the overload resolution. template <typename T> void bar (T); template <typename T> void bar (const std::vector<T> &);
--
Martin
Martin Vejnar wrote: Mark P wrote: Martin Vejnar wrote: Mark P wrote:
There are rules. Compiler cannot choose anything arbitrarily.
That said, let's review your code.
template <typename T> void foo (T &); template <typename T> void foo (const std::vector<T> &);
When you call 'foo(std::vector<int>&)', the templates get specialized and are both added to the set of candidate functions. Normal overload resolution is then performed on this set. The result is rather straightforward and easily understandable:
OK, so you've already hit upon a point of confusion for me.
When I write code like this:
vector<int> vi; foo(vi);
The first sentence you wrote ("When you call...") suggests that I am calling foo(vector<int>&) as opposed to foo(vector<int>), and as far as I can tell this distinction ultimately accounts for the difference in behavior observed below.
Is this how a compiler always interprets a function call? That is, before any overload resolution and implicit conversion, are the arguments of a function assumed to be references (to their static types)?
Not really. I merely wanted to emphasise that 'vi' is an lvalue and can be bound to a non-const reference (if it wasn't an lvalue, the first 'foo' would not participate in the resolution). Sorry for the confusion.
The actual rules used in overload resolution are rather complex. If you want to get a deeper insight into this subject, you'll have no choice, but to read through chapter [13.3] of the Standard. Or get a really good book.
Following paragraph gives the reason for the result of an overload resolution applied to the above code:
[13.3.3.2/3] [...] Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if [...] - S1 and S2 are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers. [...]
Funny, I was just looking at that section of the standard an hour ago
trying to make sense of this, and I dismissed that clause as
inapplicable because the types (minus cv-quals) weren't the same, one
being T and the other being vector<T>. But now that you highlight it
for me, I see that following template specialization they are of course
the same.
So that explains the behavior regarding foo-- the standard simply
declares that conversion to T& is better than conversion to const T&.
Regarding bar, where the candidate conversions are to T (not T&) and
const T&, is the following accurate? Both conversions are specified by
the standard as having rank "Exact Match" and therefore neither
conversion is better than the other. Because of this, the more
specialized template is chosen (as you pointed out in an earlier
message, below).
Thanks again for your very clear and helpful explanations.
Regards,
Mark // Following will be chosen void foo (std::vector<int> &);
// This requires worse implicit conversion sequence than // the first function and will not be called. void foo (const std::vector<int> &);
When it comes to the 'bar' function, normal overload resolution will fail, since neither function is better than the other.
// The call to 'bar(std::vector<int> &)' is ambigous. void bar (std::vector<int>); void bar (const std::vector<int> &);
Try that. Specialize the templates by hand. The code shouldn't compile.
When normal overload resolution fails and the candidate functions are templates, a _partial function template ordering_ [14.5.5.2] comes to play. In essence, the most specialized function template is chosen.
// The second function template is more specialised than the first // and thus shall be selected by the overload resolution. template <typename T> void bar (T); template <typename T> void bar (const std::vector<T> &);
Mark P wrote: Martin Vejnar wrote: The actual rules used in overload resolution are rather complex. If you want to get a deeper insight into this subject, you'll have no choice, but to read through chapter [13.3] of the Standard. Or get a really good book.
Following paragraph gives the reason for the result of an overload resolution applied to the above code:
[13.3.3.2/3] [...] Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if [...] - S1 and S2 are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers. [...]
Funny, I was just looking at that section of the standard an hour ago trying to make sense of this, and I dismissed that clause as inapplicable because the types (minus cv-quals) weren't the same, one being T and the other being vector<T>. But now that you highlight it for me, I see that following template specialization they are of course the same.
So that explains the behavior regarding foo-- the standard simply declares that conversion to T& is better than conversion to const T&.
Regarding bar, where the candidate conversions are to T (not T&) and const T&, is the following accurate? Both conversions are specified by the standard as having rank "Exact Match" and therefore neither conversion is better than the other. Because of this, the more specialized template is chosen (as you pointed out in an earlier message, below).
Yes, precisely. They are both "Identities", thus having "Exact Match"
rank. For 'T' it's obvious, for 'const T &' I'd say the following applies:
[13.3.3.1.4/2]
When a parameter of reference type is not bound directly to an argument
expression, the conversion sequence is the one required to convert the
argument expression to the underlying type of the reference according to
13.3.3.1. Conceptually, this conversion sequence corresponds to
copy-initializing a temporary of the underlying type with the argument
expression. Any difference in top-level cv-qualification is subsumed by
the initialization itself and does not constitute a conversion.
The parameter is not bound directly, since parameter's underlying type
and the argument's type are different ('T' and 'const T'). cv-qualifiers
are discarded (as they are not nessesary for the conceptual
copy-initialization). An implicit converision sequence from 'T' to 'T'
is a standard conversion sequence Identity. Thanks again for your very clear and helpful explanations.
You're welcome. From time to time, it's nice to talk to someone who
takes the time to read the Standard :-).
--
Martin This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: NotGiven |
last post by:
I am researching the best place to put pictures. I have heard form both
sides and I'd like to know why one is better than the other.
Many thanks!
|
by: mike420 |
last post by:
In the context of LATEX, some Pythonista asked what the big
successes of Lisp were. I think there were at least three *big*
successes.
a. orbitz.com web site uses Lisp for algorithms, etc.
b....
|
by: bearophile |
last post by:
Ville Vainio:
>It's highly typical for the newbies to suggest improvements to the
>language. They will usually learn that they are wrong, but the
>discussion that ensues can be fruitfull anyway...
|
by: Rabbit63 |
last post by:
Hi:
I want to show a set of records in the database table on the clicnt browser.
I have two ways to do this (writen in JScript):
1.The first way is:
<%
var sql = "select firstname from...
|
by: Markus Dehmann |
last post by:
I have n sets of elements. I want to find elements that occur more than once
in more than one set.
Maybe the following example shows what I mean:
S1 = {1,2,3,2,4}
S2 = {2,2,4,5,4}
S2 =...
|
by: Joerg Schuster |
last post by:
Hello,
Python regular expressions must not have more than 100 capturing
groups. The source code responsible for this reads as follows:
# XXX: <fl> get rid of this limitation!
if...
|
by: Mike MacSween |
last post by:
S**t for brains strikes again!
Why did I do that? When I met the clients and at some point they vaguely
asked whether eventually would it be possible to have some people who could
read the data...
|
by: sparks |
last post by:
We get more and more data done in excel and then they want it imported
into access.
The data is just stupid....values of 1 to 5 we get a lot of 0's ok
that alright but 1-jan ?
we get colums...
|
by: Sky |
last post by:
I have been looking for a more powerful version of GetType(string) that will
find the Type no matter what, and will work even if only supplied
"{TypeName}", not the full "{TypeName},{AssemblyName}"...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
| |