I'm trying to write some kind of preprocessor monstrosity to make simple ctors.
This compiles with g++ -std=c++17
:
template<typename T>
struct foo{
T x;
foo(T _x):x(_x){}
};
auto x=foo(3);
But it would be hard for the monstrosity to know the type of x
, so I tried this:
template<typename T>
struct foo{
T x;
foo(decltype(x) _x):x(_x){}
};
auto x=foo(3);
Which fails (class template argument deduction failed
). But decltype(x)
is just T
anyway, right? So why aren't the code samples equivalent?
What you've written is kind of circular logic. Think of it like this.
The compiler sees foo(3)
. foo
names a class template, so it attempts to perform class template argument deduction in order to figure out what the T
in foo
should be.
CTAD starts off by taking all of the constructors and building template deduction guides out of them. You have one constructor, so the guide for it would have to look like:
template<typename T> foo(decltype(foo<T>::x) _x) -> foo<T>;
In order to deduce the template parameter T
for foo
, you would need to instantiate foo
... with T
. Which you don't have yet because figuring out what T
is is why you built this deduction guide in the first place.