while experimenting with the answer from This post, ended up with the following piece of code:
#include <iostream>
#include <typeinfo>
namespace Test
{
struct MyPtr
{
double operator, (int Input)
{
std::cout << "Operator, called" << std::endl;
return 1.0;
}
MyPtr operator* ()
{
std::cout << "operator* called" << std::endl;
return *this ;
}
MyPtr operator++ ()
{
std::cout << "operator++ called" << std::endl;
return *this;
}
MyPtr operator!= (const MyPtr& Other)
{
std::cout << "operator!= called" << std::endl;
return *this;
}
};
struct Foo
{
MyPtr Ptr;
};
MyPtr begin(Foo& t)
{
return t.Ptr;
}
MyPtr end(Foo& t)
{
return t.Ptr;
}
}
int main()
{
std::cout << typeid(decltype(++begin(std::declval<Test::Foo&>()),
*begin(std::declval<Test::Foo&>()),
std::true_type{})).name() <<std::endl;
}
which yields:
d
Here, d comes from the comma operator. However, as the last expression inside the decltype specifier is std::true_type{}, why does the decltype specifier resolves to the type returned by the comma operator instead of std::true type.
My Theory is that std::true_type can be implicitly cast into an int, which operator,() here takes as a parameter, hence the decltype expression is equivalent to:
std::cout << typeid(decltype(++begin(std::declval<Test::Foo&>()),
declval<double&>())).name() <<std::endl;
Can you confirm this is correct?
What i am planning on doing when i will have a better grasp of the compiler's behavior, i plan on replacing the contents of the decltype specifier with:
std::cout << typeid(decltype(void(++begin(std::declval<Test::Foo&>())),
void(*begin(std::declval<Test::Foo&>())),
std::true_type{})).name() <<std::endl;
which will prevent operator,() from matching, even if it is overridden. Can you also confirm this is correct?
Aucun commentaire:
Enregistrer un commentaire