Вопрос

So I have the following bit of code:

template <typename Type>
class Delegate
{
public:
    Delegate(Type x)
    {
    }
};

void Method()
{
}

int main()
{
    Delegate d(&Method);
    return 0;
}

My question is: why can't the compiler deduce the template type based on what's passed into the constructor? The compile error I get is: Argument list for class template Delegate is missing. I understand that, but I thought type inference could overcome this to allow for cleaner syntax.

Это было полезно?

Решение

Because template parameter deduction only applies to functions. Class templates require parameters explicitly, always.

That's why many templates have a "named constructor" a function that simply constructs a temporary instance, but by virtue of being a function template rather than class template deduces parameters. For example std::make_pair.

C++11 introduced this new meaning of auto that actually allows you to deduce type of variable. So if you have C++11, you can create a "named constructor" for your class, like:

template <typename Type>
Delegate<Type> delegate(Type x) { return Delegate<Type>(x); }

and you can create a variable of deduced type with it like:

auto d = delegate(&Method);

Note, that this deduces d to be exactly the type returned by the initializer (you can have auto & or auto && if you want, but not much beyond that). This is way easier than trying to deduce hypothetical Delegate d(&Method), because that would involve cyclical dependency between deducing the type depending on overload resolution between constructors and the set of viable constructors depending on the deduced type (remember, constructors can be overloaded and types can be partially specialized).

Другие советы

It's for the same reason that this won't work:

// attempt to create a std::vector<std::string> of ten "x" strings:
std::vector v(10, "x");

In fact, it should result in the very same error message.

Use something like this to use type deduction:

template <class Type>
Delegate<Type> MakeDelegate(Type const &x)
{
    return Delegate<Type>(x);
}

Or just do as you'd do with a std::vector and declare the type explictly.

By the way, main must return int, and arguments of unknown type (i.e. in templates) should be passed with const&.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top