//template.h using MSVC++ 2010
#pragma once
#include <iostream>
using std::ostream;
template <typename T, typename U> class Pair {
private:
T first;
U second;
public:
// Pair() ;
Pair ( T x = T() , U y = U() ) ;
template<typename T, typename U>
friend ostream& operator<< ( ostream& thisPair, Pair<T, U>& otherPair );
};
template <typename T, typename U>
Pair<T, U>::Pair ( T x , U y ) : first ( T ( x ) ), second ( U ( y ) )
{cout << x << y;}
template <typename T, typename U>
ostream& operator<< ( ostream& os, Pair<T, U>& otherPair )
{
os << "First: " << otherPair.first
<< " "<< "Second: " << otherPair.second << endl;
return os;
}
//template.cpp
int main()
{
int a = 5, b = 6;
Pair<int,int> pair4();
Pair<int, int> pair1 ( a, b );
cout<<pair4;
cout<<pair1;
return 0;
}
How to make a constructor or a member function to take default value?
The code above is giving linker error for pair4 when using cout statement.
The code works perfectly when cout<<pair4(); is commented.
I am trying to mimic a constructor taking 0,1 or 2 argument using a single default constructor in a template class.
Apart from other errors like shadowing template parameters (which MSVC++ wrongly ignores), the problem is here:
Pair<int,int> pair4();
This declares a function instead of a variable. This is because it can be syntactically both and C++ standard selects the most vexing parse: anything that can be interpreted by compiler as a declaration, will be interpreted as a declaration. The linker error then is that you try to print to cout address of a function that is never defined (has no address).
Side note: in GCC and Clang, you can actually link this because the address is immediatelly converted to bool for operator << (there is no operator for printing function pointers to ostream and bool is the only available implicit conversion) which will always result in true (address of a declared function can never be nullptr) so the address itself is optimized away.
The fix is very simple:
Pair<int,int> pair4;
Related
i have problem to make it work in this line
Polynomial p2( pf_1 );
i don't know is conversion constructor or conversion operator and how to deal with different type template but same size
std::cout << "-------- " << __func__ << " --------\n";
Polynomial<float,2> pf_1;
pf_1[0] = 1.1;
pf_1[1] = -2.2;
pf_1[2] = 1.1;
std::cout << pf_1 << std::endl;
Polynomial<int,2> p2( pf_1 ); // convert
std::cout << p2 << std::endl;
template< typename T, int N >
class Polynomial
{
public:
friend std::ostream& operator<< <T, N>( std::ostream &out, Polynomial<T, N> const& pol );
Polynomial();
T& operator[](int pos);
T GetDegree(int pos)const;
void SetDegree(int pos, T value);
private:
T coeff[N];
};
from (float)
1.1 -2.2*x^1 +1.1*x^2
convert to (int)
1 -2*x^1 +x^
Either a converting constructor or a conversion operator could work here. But when both are possible, the converting constructor is usually more straightforward.
So you want a single type like Polynomial<int, 2> to be convertible from a family of other types including Polynomial<double, 2> and Polynomial<short int, 2>. This suggest you want not just a simple converting constructor, but a member template constructor. The degree N should stay the same as the class template, but we introduce a new type parameter for the source coefficient type:
template< typename T, int N >
class Polynomial
{
public:
template< typename U >
explicit Polynomial(const Polynomial<U, N>& src);
// ...
};
I've marked it explicit, which will support your Polynomial<int,2> p2( pf_1 ); example, but forbid implicit conversions. This is up to you, but implicit conversions can sometimes lead to unfortunate surprises.
If the constructor template will be defined outside the class template, note you need to list the class template parameters and then the member template parameters to write the definition:
template< typename T, int N > template< typename U >
Polynomial<T, N>::Polynomial(const Polynomial<U, N>& src) : // ...
Here is my unsuccessful attempt at detecting whether a free-standing function void set( T& , void (T::*Func)( const char* ) , const char* str ) exists for any class/struct T, in C++98/03.
#include <iostream>
#include <typeinfo>
struct Foo;
struct Bar;
struct Fuu;
void set( Foo& , void (Foo::*Func)( const char* ) , const char* str )
{
}
void set( Bar& , void (Bar::*Func)( const char* ) , const char* str )
{
}
template <typename T>
class setter_is_implemented
{
public:
typedef void (*SetterFunction)( T& , void (T::*)( const char* ) , const char* );
typedef char one;
typedef long two;
template <typename C> static one test( C c, SetterFunction = c ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof( test<T>(&set)) == sizeof(one) };
};
int main()
{
std::cout << setter_is_implemented<Foo>::value << std::endl;
std::cout << setter_is_implemented<Bar>::value << std::endl;
std::cout << setter_is_implemented<Fuu>::value << std::endl;
}
GCC error message
Test.cpp:24:66: error: ‘c’ was not declared in this scope
template <typename C> static one test( C c, SetterFunction = c ) ;
^
Test.cpp: In instantiation of ‘class setter_is_implemented<Foo>’:
Test.cpp:33:44: required from here
Test.cpp:28:35: error: address of overloaded function with no contextual type information
enum { value = sizeof( test<T>(&set)) == sizeof(one) };
^
Test.cpp: In instantiation of ‘class setter_is_implemented<Bar>’:
Test.cpp:34:44: required from here
Test.cpp:28:35: error: address of overloaded function with no contextual type information
Test.cpp: In instantiation of ‘class setter_is_implemented<Fuu>’:
Test.cpp:35:44: required from here
Test.cpp:28:35: error: address of overloaded function with no contextual type information
AFAIK, taking the address of an overloaded function happens before overload resolution, so SFINAE cannot work in that way. This is also harder because your function returns void (otherwise, one would just check the size of the result ). My C++03 metaprogramming is rusty, but this should work (live on coliru):
namespace setter_is_implemented_detail {
struct dummy1 { char c[2]; };
typedef char dummy2;
dummy2 operator,(dummy1, dummy1);
template<typename T> dummy1 set(T const&,...);
template <typename T>
struct impl
{
typedef void (T::*FT)( const char* );
static T& x;
enum { value = sizeof( set(x,static_cast<FT>(0),static_cast<const char*>(0)), dummy1() ) != sizeof(dummy2) };
};
}
template <typename T>
struct setter_is_implemented: setter_is_implemented_detail::impl<T>{};
note a few things:
set() needs to be found by ADL here (not a big deal, as far as I can tell from your problem description)(*)
the comma operator trick(**) is needed due to the void return type; in gcc, you can take the sizeof(void), so the code can be simplified there
this won't work for non object types (due to the static T&). It can be made to work though, if you need so...
(*) Note that this cannot work for every possible set() overload; this is true for any sfinae, even in c++17, set() must always be sfinae-friendly in order to work.
If you need to match sfinae-friendly set() overloads exactly, it's still possible to do it, but it's more complex; I'd do it in two phases: first you use the above code to find possible candidates, then you check the function pointer conversion, somewhat like you do in your original code ..
(**) This trick works because if set() has void return type (and hence exists) the comma is always interpreted as the built-in comma operator (see c++03[3.9.1/9]: "An expression of type void shall be used only as an expression statement (6.2), as an operand of a comma expression[...]") resulting in the right-most expression. Otherwise, the dummy set and comma operator are used.
I want to test whether a class is streamable to ostream& by seeing whether an overload for operator<< is provided. Based on these posts, I tried to write another version using C++11. This is my attempt:
#include <iostream>
#include <type_traits>
namespace TEST{
class NotDefined{};
template<typename T>
NotDefined& operator << (::std::ostream&, const T&);
template <typename T>
struct StreamInsertionExists {
static std::ostream &s;
static T const &t;
enum { value = std::is_same<decltype(s << t), NotDefined>() };
};
}
struct A{
int val;
friend ::std::ostream& operator<<(::std::ostream&, const A&);
};
::std::ostream& operator<<(::std::ostream& os, const A& a)
{
os << a.val;
return os;
}
struct B{};
int main() {
std::cout << TEST::StreamInsertionExists<A>::value << std::endl;
std::cout << TEST::StreamInsertionExists<B>::value << std::endl;
}
But this fails to compile:
test_oper.cpp:40:57: error: reference to overloaded function could not be resolved; did you mean to call it?
std::cout << TEST::StreamInsertionExists<A>::value << std::endl;
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ostream:1020:1: note:
possible target for call
endl(basic_ostream<_CharT, _Traits>& __os)
test_oper.cpp:30:17: note: candidate function not viable: no known conversion from 'TEST::NotDefined' to '::std::ostream &'
(aka 'basic_ostream<char> &') for 1st argument
::std::ostream& operator<<(::std::ostream& os, const A& a)
test_oper.cpp:15:15: note: candidate template ignored: couldn't infer template argument 'T'
NotDefined& operator << (::std::ostream&, const T&);
However, if I replace the line
enum { value = std::is_same<decltype(s << t), NotDefined>() };
with
static const bool value = std::is_same<decltype(s << t), NotDefined>();
then everything compiles.
Why is there such a difference between the enum and the bool?
value is an enum of anonymous name in StreamInsertionExists<T>. When you try to do:
std::cout << StreamInsertionExists<T>::value;
The compiler is doing overload lookup on operator<<(std::ostream&, StreamInsertionExists<T>::E). In the typical case, it'd do integral promotion on the enum and stream it as int. However, you additionally defined this operator:
template<typename T>
NotDefined& operator << (std::ostream&, const T&);
That is a better match for the enum than the int version (Exact Match vs integral promotion), so it is preferred. Yes, it's a function template, but non-templates are only preferred if the conversion sequences match - and in this case they don't.
Thus, this line:
std::cout << TEST::StreamInsertionExists<A>::value << std::endl;
which is:
operator<<(operator<<(std::cout, TEST::StreamInsertionExists<A>::value), std::endl);
And the inner most operator<< call will use your NotDefined& template. Thus, the next step would be to find an appropriate function call for:
operator<<(NotDefined&, std::endl);
and there is no such overload for operator<< hence the error.
If you change value to be bool, there is no such problem because there is an operator<< that takes bool exactly: #6. That said, even with bool, your trait is still incorrect as it always returns false. Your NotDefined version actually returns a reference, so you'd have to check against that. And also, NotDefined& means not defined, so you'd have to flip the sign:
static const bool value = !std::is_same<decltype(s << t), NotDefined&>();
However, this is particularly error prone. Now cout << B{}; instead of failing to compile would instead give you a linker error, and cout << B{} << endl; gives you the same confusing overload error involving endl instead of simply statying that you can't stream a B.
You should prefer to just do:
template <typename...>
using void_t = void;
template <typename T, typename = void>
struct stream_insertion_exists : std::false_type { };
template <typename T>
struct stream_insertion_exists<T, void_t<
decltype(std::declval<std::ostream&>() << std::declval<T>())
> > : std::true_type { };
In the sample code below, it shows that boost::tuple can be created implicitly from the first template argument.
Because of that I am not able to write a << operator as it becomes ambiguous.
Also I don't understand why ostringstream& << float is also ambiguous. This does not have any implicit construction. Why does this also give ambiguous error?
#include <iostream>
#include <boost/tuple/tuple.hpp>
#include <sstream>
#include <string>
using namespace std;
class Myclass
{
};
typedef boost::tuple<int,float,Myclass> Mytuple;
ostringstream& operator<<(ostringstream& os_, Mytuple tuple_)
{
float f = tuple_.get<1>();
//os_ << (int)tuple_.get<0>(); // Error because int is implicitly converted into Mytuple. WHYY?
//os_ << tuple_.get<1>(); // No Clue Why this is ambiguous.
//os_ << tuple_.get<2>(); // Error because no matching operator. Fine.
return os_;
}
int main()
{
Mytuple t1;
t1 = 3; // Working because int is implicitly converted into Mytuple!! WHY?
//t1 = 3.0f; // Error because no matching constructor. Fine.
return 0;
}
Error Mesasge:
tupleTest2.C:18: error: ISO C++ says that these are ambiguous, even
though the worst conversion for the first is better than the worst
conversion for the second:
The problem is not with the tuple, but with your operator. This works fine :
ostream& operator<<(ostream& os_, Mytuple tuple_)
{
os_ << tuple_.get<0>(); // Error because int is implicitly converted into Mytuple. WHYY?
os_ << tuple_.get<1>(); // No Clue Why this is ambiguous.
//os_ << tuple_.get<2>(); // Error because no matching operator. Fine.
return os_;
}
The problem is that the ostringstream inherit operator<< from ostream, which has this signature : ostringstream& operator<<(ostringstream& os_, Mytuple tuple_) is allowed. Then the
ostream& operator<<(ostream& os, T t)
(change T with all available types in c++, see operator<< reference page
EDIT
Here is a simplified example (without a tuple) :
ostringstream& operator<<(ostringstream& os_, Mytuple tuple_)
{
const int i = tuple_.get<0>();
os_ << i; // error in this line
return os_;
}
and the error is now :
dfg.cpp: In function ‘std::ostringstream& operator<<(std::ostringstream&, Mytuple)’:
dfg.cpp:18: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/lib/gcc/i386-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/ostream.tcc:111: note: candidate 1: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
dfg.cpp:14: note: candidate 2: std::ostringstream& operator<<(std::ostringstream&, Mytuple)
The above error message says : it is not possible to choose between two operators operator<<(ostream&,...) and operator<<(ostringstream&,...). This also raises another question : why on earth do you needoperator<<(ostringstream&,...)`?
When you write
os << tuple_.get<0>();
there is no function that matches both parameters. Instead the compiler has a choice to apply an implicit conversion on either parameter
std::ostream << int
or
std::ostringstream << MyTuple
The latter would happen with the boost::tuple constructor that can take any number of arguments up to number of tuple elements. (And with float it fails, because float is convertible to int.)
When overloading stream operators, use the base class as the left hand side (ostream or even basic_ostream<CharT, Traits>.
Edit: You could disambiguate the call by casting the first argument.
ostringstream& operator<<(ostringstream& os_, Mytuple tuple_)
{
static_cast<std::ostream&>(os_) << tuple_.get<0>();
static_cast<std::ostream&>(os_) << tuple_.get<1>();
static_cast<std::ostream&>(os_) << tuple_.get<2>(); // Error because no matching operator. Fine.
return os_;
}
However, overloading the operator with ostringstream is still a bad idea, because it won't work with operator chaining.
MyTuple a, b;
ostringstream ss;
ss << a << ' ' << b;
will invoke:
1) ostringstream& operator<<(ostringstream& os_, Mytuple tuple_)
2) ostream& ostream::operator<<(char)
3) ostream& operator<<(ostream&&, boost::tuple<int,float,Myclass>
All those people telling you to use ::std::ostream for the type instead of ::std::ostringstream are absolutely correct. You shouldn't be using ::std::ostringstream that way.
But my main beef with your code is the distressing lack of generality. It only works for one particular tuple type, and not all of them.
So I wrote an operator << for ::std::tuple in C++0x that works for any tuple who's members can be individually written using operator <<. It can probably be translated relatively easily to work with Boost's tuple type. Here it is:
template < ::std::size_t fnum, typename tup_type>
void print_fields(::std::ostream &os, const tup_type &val)
{
if (fnum < ::std::tuple_size<tup_type>::value) {
::std::cerr << "Fred " << fnum << '\n';
os << ::std::get<fnum, tup_type>(val);
if (::std::tuple_size<tup_type>::value > (fnum + 1)) {
os << ", ";
}
print_fields<fnum + 1, tup_type>(os, val);
}
}
template < ::std::size_t fnum, typename... Elements>
class field_printer;
template <typename... Elements>
class field_printer<0, Elements...> {
public:
typedef ::std::tuple<Elements...> tup_type;
static void print_field(::std::ostream &os, const tup_type &val) {
}
};
template < ::std::size_t fnum, typename... Elements>
class field_printer {
public:
typedef ::std::tuple<Elements...> tup_type;
static void print_field(::std::ostream &os, const tup_type &val) {
constexpr auto tupsize = ::std::tuple_size<tup_type>::value;
os << ::std::get<tupsize - fnum, Elements...>(val);
if (fnum > 1) {
os << ", ";
}
field_printer<fnum - 1, Elements...>::print_field(os, val);
}
};
template <class... Types>
::std::ostream &operator <<(::std::ostream &os, const ::std::tuple<Types...> &val)
{
typedef ::std::tuple<Types...> tup_type;
os << '(';
field_printer< ::std::tuple_size<tup_type>::value, Types...>::print_field(os, val);
return os << ')';
}
This prints out the tuple as "(element1, element2, ...elementx)".
I observed some inconsistency between two compilers (g++ 4.5, VS2010 RC) in the way they match lambdas with partial specializations of class templates. I was trying to implement something like boost::function_types for lambdas to extract type traits. Check this for more details.
In g++ 4.5, the type of the operator() of a lambda appears to be like that of a free standing function (R (*)(...)) whereas in VS2010 RC, it appears to be like that of a member function (R (C::*)(...)). So the question is are compiler writers free to interpret any way they want? If not, which compiler is correct? See the details below.
template <typename T>
struct function_traits
: function_traits<decltype(&T::operator())>
{
// This generic template is instantiated on both the compilers as expected.
};
template <typename R, typename C>
struct function_traits<R (C::*)() const> { // inherits from this one on VS2010 RC
typedef R result_type;
};
template <typename R>
struct function_traits<R (*)()> { // inherits from this one on g++ 4.5
typedef R result_type;
};
int main(void) {
auto lambda = []{};
function_traits<decltype(lambda)>::result_type *r; // void *
}
This program compiles on both g++ 4.5 and VS2010 but the function_traits that are instantiated are different as noted in the code.
I believe that GCC is noncompliant. N3092 §5.1.2/5 says
The closure type for a
lambda-expression has a public inline
function call operator (13.5.4) whose
param- eters and return type are
described by the lambda-expression’s
parameter-declaration-clause and
trailing- return-type respectively.
This function call operator is
declared const (9.3.1) if and only if
the lambda- expression’s
parameter-declaration-clause is not
followed by mutable.
So while many things about the closure object's type are implementation-defined, the function itself must be a member to be public and must be a nonstatic member to be const.
EDIT: This program indicates that operator() is a member function on GCC 4.6, which is essentially the same as 4.5.
#include <iostream>
#include <typeinfo>
using namespace std;
template< class ... > struct print_types {};
template<> struct print_types<> {
friend ostream &operator<< ( ostream &lhs, print_types const &rhs ) {
return lhs;
}
};
template< class H, class ... T > struct print_types<H, T...> {
friend ostream &operator<< ( ostream &lhs, print_types const &rhs ) {
lhs << typeid(H).name() << " " << print_types<T...>();
return lhs;
}
};
template< class T >
struct spectfun {
friend ostream &operator<< ( ostream &lhs, spectfun const &rhs ) {
lhs << "unknown";
return lhs;
}
};
template< class R, class ... A >
struct spectfun< R (*)( A ... ) > {
friend ostream &operator<< ( ostream &lhs, spectfun const &rhs ) {
lhs << "returns " << print_types<R>()
<< " takes " << print_types<A ...>();
return lhs;
}
};
template< class C, class R, class ... A >
struct spectfun< R (C::*)( A ... ) > {
friend ostream &operator<< ( ostream &lhs, spectfun const &rhs ) {
lhs << "member of " << print_types<C>() << ", " << spectfun<R (*)(A...)>();
return lhs;
}
};
template< class T >
struct getcall {
typedef decltype(&T::operator()) type;
};
int main() {
int counter = 0;
auto count = [=]( int ) mutable { return ++ counter; };
cerr << spectfun< getcall<decltype(count)>::type >() << endl;
}
output:
member of Z4mainEUlvE_, returns i takes i
EDIT: It looks like the only problem is that pointers to certain closure call operators fail to match ptmf template patterns. The workaround is to declare the lambda expression mutable. This is meaningless if there is no capture and only (aside from fixing the problem) seems to change the const-ness of the call operator.
template< class T >
struct getcall {
typedef decltype(&T::operator()) type;
static type const value;
};
template< class T >
typename getcall<T>::type const getcall<T>::value = &T::operator();
int main() {
auto id = []( int x ) mutable { return x; };
int (*idp)( int ) = id;
typedef decltype(id) idt;
int (idt::*idptmf)( int ) /* const */ = getcall< decltype(id) >::value;
cerr << spectfun< decltype(idp) >() << endl;
cerr << spectfun< decltype(idptmf) >() << endl;
cerr << spectfun< getcall<decltype(id)>::type >() << endl;
output:
returns i takes i
member of Z4mainEUliE0_ , returns i takes i
member of Z4mainEUliE0_ , returns i takes i
Without the mutable and with the const, spectfun does not print signatures for either of the last two queries.
Read n3043. Lambdas are now convertible to function pointers provided they don't have any state. I believe (...but do not know) GCC initially implemented this behavior accidentally, "fixed it", now will be re-adding it to 4.5 or 4.6. VC10 implemented lambdas correctly as initially designed, but not conforming to the latest working papers with n3043.
I think gcc developers has a good reason for this behaivor. Remember, a static function do not have a "this" pointer, and when it is being actually called, the caller do not required to pass the "this" pointer. So this is a small performance optimisation when it is actually nothing contained in the closure object. And you can see the G++ developer leave you a way to workaround by declaring the lambda expression as "mutable" (remember you actually do not have anything to mutate).