Reputation: 323
I have a class with variadic template parameters:
template<typename... Args>
class something {
public:
something(Args&&... args); // omitted for brevity
}
I have a function that accepts a list of arguments and returns an object of this class:
template<typename... Args>
auto make_something(Args&&... args) {
return something<Args...>(std::forward<Args>(args)...);
}
If I call it like so:
something<int, std::string> s = make_something<int, std::string>(1, "");
it compiles and works fine.
but if I try to pass a const argument, I get compile errors:
const std::string t = "";
something<int, std::string> s1 = make_something(1, t); // no viable conversion from something<... const basic_string<char>> to something<... std::string>
How can I successfully pass const and then, idk, cast the result to the requested type, parametrized by a non-const type?
I suspect it has something to do with the type of the object I'm returning but I don't actually know what to replace auto
with in this case.
Upvotes: 0
Views: 64
Reputation: 62694
There are two options, depending on if you really want to have something<int, const std::string &>
be a type that make_something(1, t)
returns.
If that is the case, you can have a converting constructor
template<typename... Args>
class something {
public:
something(Args&&... args); // omitted for brevity
template<typename... OtherArgs>
something(something<OtherArgs...>); // convert each OtherArgs into Args
}
In the alternative, where you want make_something(1, t)
to result in something<int, std::string>
template<typename... Args>
class something {
public:
template<typename... OtherArgs>
something(OtherArgs&&...); // use each OtherArgs for Args
}
template <typename... Args>
auto make_something(Args&&... args)
{
return something<std::decay_t<Args>...>(std::forward<Args>(args)...);
}
Upvotes: 1
Reputation: 217275
You might do (if relevant):
template <typename... Args>
auto make_something(Args&&... args)
{
return something<std::decay_t<Args>...>(std::forward<Args>(args)...);
}
So you got something<int, std::string>
instead of something<int, const std::string&>
Upvotes: 2