@NathanOliver mentioned using concepts and constraints with C++20 in the comment of his answer, so here's how you can do it with C++20 constraint:
template <typename Scalar>
struct B
{
public:
template <typename ... Args>
requires std::constructible_from<Scalar, Args...>
B(Args ... args) : v(std::forward<Args>(args) ...) {}
Scalar v;
};
Attempting to construct a B<A<double>> from something that cannot convert to double will create a compiler error:
B<A<double>> ba = "ok"; // Compiler error
// candidate template ignored: constraints not satisfied [with Args = <const char *>]
// because 'std::constructible_from<A<double>, const char *>' evaluated to false
Note, this doesn't really have an equivalent form that can be written as a concept directly:
template<std::constructible_from<Scalar> ... Args>
Would be the equivalent of, which is wrong in multiple ways:
template<typename Args_1, typename Args_2>
requires std::constructible_from<Args_1, Scalar> && std::constructible_from<Args_2, Scalar>
However, if you know you will only need constructor with a single parameter, then you can potentially use std::convertible_to:
template <typename Scalar>
struct B
{
public:
template <std::convertible_to<Scalar> Arg>
B(Arg arg) : v(std::forward<Arg>(arg)) {}
Scalar v;
};
This do require an implicit conversion from Arg to Scalar however, so either the constructor of Scalar, or a conversion function from Arg to Scalar must not be explicit.
Side note, the base constructor B(Scalar a): v(a) {} at this point is basically redundant, as it will be covered by the templated constructor.