Reputation: 1975
Here is a standalone use case of what I am trying to achieve
//Bar.hpp
#ifndef BAR_HPP
#define BAR_HPP
constexpr bool areNamesEqual(const char* name1,const char* name2)
{
return ((*name1 == *name2) && (*name1 == '\0' || areNamesEqual(name1 + 1,name2 + 1)));
}
#endif
Then I have a class which uses this comparison utility as follows
// Foo.hpp
#ifndef FOO_HPP
#define FOO_HPP
#include "Bar.hpp"
class Foo
{
public:
template<typename T_0>
Foo(const T_0 & var_0)
{
static_assert(areNamesEqual(T_0::formatter_name,"Hole"),"Incorrect hole type supplied!");
}
};
#endif
Finally I have another class, which actually provides an argument for the comparison as follows
// Hole.hpp
#ifndef HOLE_HPP
#define HOLE_HPP
class Hole {
public:
Hole(double dx) : d(dx) {}
static constexpr const char* formatter_name = "Hole";
private:
double d;
};
#endif
In my main.cpp when I invoke this as below
//main.cpp
#include "Foo.hpp"
#include "Hole.hpp"
int main()
{
Foo f(43);
return 0;
}
g++(6.3) with --std=c++14 gives me following error
In file included from main.cpp:1:0:
Foo.hpp: In instantiation of ‘Foo::Foo(const T_0&) [with T_0 = int]’:
main.cpp:6:13: required from here
Foo.hpp:12:36: error: ‘formatter_name’ is not a member of ‘int’
static_assert(areNamesEqual(T_0::formatter_name,"Hole"),"Incorrect hole type supplied!");
Why cant the compiler convert double
type to Hole
class implicitly ?
I am not sure if conversion operator of Hole class would help me out here.
:UPDATE:
Updated the snippet to show the error for int
literal.
Upvotes: 1
Views: 57
Reputation: 8396
Let's analyse the compiler error:
Foo.hpp: In instantiation of ‘Foo::Foo(const T_0&) [with T_0 = int]’:
Means T_0
is deduced to type int
(side note: are you sure you are not giving the error when you tried with 43
literal, instead of 43.0
?)
So, the type of T_0
is fixed from here. Then:
Foo.hpp:12:36: error: ‘formatter_name’ is not a member of ‘int’.
Which is true: the primitive type int
does not have members at all, so it does not have formatter_name
member in particular.
This explains the error, which is as-prescribed by the C++ standard.
Now, you mention expecting conversion, is it because of the non-explicit
constructor for Hole
taking a double
?
If so, this conversion would implicitly happen only if you gave a double to a "context" expecting an Hole
instance.
E.g, if you changed the Foo
initialization to Foo f<Hole>(43.0);
or Foo f(Hole{43.0});
This is absolutely not the case in you example: you give a double to Foo
constructor that is templated on the argument type, and you do not force the template type yourself. So function template type deduction kicks-in, and it exactly matches the argument type. Additionally, implementing any conversion operator would not change that fact.
Upvotes: 2