I currently have a class template that takes a series of types. Each type may need to be instantiated with the class, itself. What I currently have is something like this:
template <typename... Types>
struct TypeList; // Not defined
struct Placeholder; // Not defined
template <typename Types, typename AnotherType = Default>
class MyClass
{
// ...
};
You can then use it like this:
typedef MyClass<TypeList<Container1<Placeholder>, Container2<std::string,
Placeholder>, OtherType>, OptionalType> MyTypedef;
MyTypedef my_object;
MyClass will replace appearances of Placeholder with itself, use the resulting types, and all is well.
The problem occurs when I try to do something like either of these:
MyTypedef *my_ptr = &my_object;
my_free_function(my_object);
Both of these cause a compiler error, because the compiler tries to instantiate Container1<Placeholder> and Container2<std::string, Placeholder> to do argument dependent lookup (ADL), and this instantiation with Placeholder, itself, fails.
I know it is possible to avoid ADL by doing, e.g.,
MyTypedef *my_ptr = std::addressof(my_object);
(my_free_function)(my_object);
However, I don’t want to burden the user of MyClass with having to constantly suppress ADL. Is there another, straightforward way to have the user provide a list of types without those types being used for ADL?
Okay, I got everything working. The trick was to use a dependent type instead of using a template, directly. My final solution was to define TypeList as follows:
Then, the users of MyClass can do
Note the addition of ‘::type’
Finally, in MyClass, I replaced
with
giving me the same type for
InternalTypeListas before.Because the dependent type
Holderhas no template parameters of it’s own, the compiler doesn’t have to instantiate the Placeholder types for ADL purposes, and everything works properly.