C++ Invoke Explicit Template Constructor

C++ invoke explicit template constructor

It's not possible. The Standard also has a note on this at 14.8.1/7

[Note: because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates. ]

Explanation: This says: Template arguments are passed in angle brackets after a function template name, such as std::make_pair<int, bool>. And constructors don't have a name of their own, but they abuse their class names in various contexts (so U<int>() means: Pass <int> to the class template U, and construct an object by calling the default constructor without arguments). Therefore, one cannot pass template arguments to constructors.

In your case, you are trying to pass template arguments in a member initializer. In that case, there's even more of a problem: It will attempt to parse and interpret t<void> as a base-class type and thinks you want to call the default constructor of a base class. This will fail, of course.

If you can live with it, you can work it around

struct T { 
template<class U> T(identity<U>);
};

struct U {
U() : t(identity<void>()) {}
T t;
};

Given identity like it's defined in boost

template<typename T> struct identity { typedef T type; };

Within C++20 you can use std::type_identity as identity type.

  • https://en.cppreference.com/w/cpp/types/type_identity

How to explicit instantiate template constructor in C++?

You're almost there, the problem is the last argument must be a reference as it's in the template declaration:

template AABB::AABB<Triangle>(const idx_t, const idx_t, const vector<Triangle>&);
// ^^^

Also, as T.C pointed out, you can remove <Triangle> because it can be inferred from the type of the argument:

template AABB::AABB(const idx_t, const idx_t, const vector<Triangle>&);

C++ explicit instantiation of template constructor of non-template class

There is no syntax like this for explicit instantiation of templated contructors in C++:

template Fraction::Fraction<int, int>(int, int, bool);
^^^^^^^^^^

You should use the following simple syntax instead:

template Fraction::Fraction(int, int, bool);

C++ - Invoking a constructor template explicitly inside a template class?

It is impossible to provide explicit template arguments to constructor templates.

The types must be inferred:

template<typename T>
template<typename TypeValue, typename TypeMin, typename TypeMax>
ScalarClamped<T>::ScalarClamped(TypeValue&& value_, TypeMin&& min_, TypeMax&& max_):
// Initialization list:
_m_tValue(std::forward<TypeValue>(value_)),
_m_tValueMax(std::forward<TypeMax>(max_)),
_m_tValueMin(std::forward<TypeMin>(min_))
// Function body:
{
Algorithm::clamp<TypeValue, TypeMin, TypeMax>(_m_tValue, _m_tValueMin, _m_tValueMax);
}

template<typename T>
ScalarClamped<T>
ScalarClamped<T>::operator+(ScalarClamped const& scalar_clamped_) const
{
return ScalarClamped<T>::ScalarClamped(
_m_tValue + scalar_clamped_._m_tValue,
_m_tValueMin,
_m_tValueMax);
}

Explicit instantiation of templated constructor for template class

It looks like you've found a GCC bug. These both name the implicitly-declared copy constructor:

template Foo<int>::Foo( const Foo<int>& foo );
template Foo<float>::Foo( const Foo<float>& foo );

Per [temp.explicit]p4,

If the declaration of the explicit instantiation names an implicitly-declared special member function (Clause 12), the program is ill-formed.

Therefore Clang is correct to reject this code.

C++ call templated constructor for template class

Data<int, MyClass, bool> is the type obtained by instantiating the class template Data with the template arguments int, MyClass, bool. So in your example, the template arguments go to Args.

There is no way to explicitly specify template arguments for a constructor. The C++ standard even says so unequivocally (§14.8.1/7):

[ Note: Because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a
function name, there is no way to provide an explicit template argument list for these function templates.
end note ]

Constructor with template arguments

Constructor template arguments must be deduced. They cannot be provided explicitly. You can get around this by providing a type tag which encodes the wanted template argument and passing it as an additional constructor argument. For example :

#include <utility>  // For std::forward

struct foo
{
// Helper tag type
template<class T>
struct type_tag {};

// The template argument T is deduced from type_tag<T>
template<class T, class ... Args>
foo(type_tag<T>, Args&&... p_args)
{
T value{ std::forward<Args>(p_args)... };
}
};

int main()
{
// Provide a type tag so the template argument can be deduced
foo bar{ foo::type_tag<int>{}, 5 };
}

C++ invoke explicit template constructor

It's not possible. The Standard also has a note on this at 14.8.1/7

[Note: because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates. ]

Explanation: This says: Template arguments are passed in angle brackets after a function template name, such as std::make_pair<int, bool>. And constructors don't have a name of their own, but they abuse their class names in various contexts (so U<int>() means: Pass <int> to the class template U, and construct an object by calling the default constructor without arguments). Therefore, one cannot pass template arguments to constructors.

In your case, you are trying to pass template arguments in a member initializer. In that case, there's even more of a problem: It will attempt to parse and interpret t<void> as a base-class type and thinks you want to call the default constructor of a base class. This will fail, of course.

If you can live with it, you can work it around

struct T { 
template<class U> T(identity<U>);
};

struct U {
U() : t(identity<void>()) {}
T t;
};

Given identity like it's defined in boost

template<typename T> struct identity { typedef T type; };

Within C++20 you can use std::type_identity as identity type.

  • https://en.cppreference.com/w/cpp/types/type_identity


Related Topics



Leave a reply



Submit