bind with enable_if'd member functions - c++

I'm getting tripped up on calling bind on an enable_if'd member function. I've worked around it using if constexpr, but I'm curious what the solution would be for this issue. The code is the simplest reproducer and not representative of the overarching problem I'm trying to solve. How can I make this work?
#include <iostream>
#include <type_traits>
#include <functional>
template <typename T>
class test {
public:
template <typename U = T>
typename std::enable_if<std::is_copy_constructible<U>::value, void>::type
foo(const T& v){
std::cout << "copy constructible";
}
template <typename U = T>
typename std::enable_if<!std::is_copy_constructible<U>::value, void>::type
foo(const T& v){
std::cout << "not copy constructible";
}
void foo_bar(const T& v){
std::cout << "test";
}
};
int main(int argn, char** argc){
test<int> myfoo;
myfoo.foo(3); //Works
auto func = std::bind(&test<int>::foo_bar, &myfoo, 3); //Works
auto func = std::bind(&test<int>::foo, &myfoo, 3); //Doesn't work
func();
return 0;
}

The problem is that U is substituted only when the member function template foo is actually called, and not when it is used inside of std::bind(). This means that when specifying &test<int>::foo inside bind(), it isn't known which of the two member function templates is going to be actually instantiated since the instantiation of definition will happen when we actually call foo(), and so the compiler can't decide which of them you're referring to. This is exactly what <unresolved overloaded function type> means in the error that you're getting:
no matching function for call to 'bind(<unresolved overloaded function type>, test<int>*, int)'
32 | auto func2 = std::bind(&test<int>::foo, &myfoo, 3); //Doesn't work
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can solve this by either specifying U explicitly, like:
&test<int>::foo<int>
or by using a lambda, like:
auto func = [&myfoo]() { myfoo.foo(3); };
There is a third way to solve this in C++20 using requires-clause as shown below. Note that the below program is well-formed but gcc and msvc incorrectly rejects it. Only clang accepts it which is the correct behavior. Demo
#include <iostream>
#include <type_traits>
#include <functional>
template <typename T>
class test {
public:
void foo(const T& v) requires std::is_copy_constructible_v<T>{
std::cout << "copy constructible";
}
void foo(const T& v) requires (!std::is_copy_constructible_v<T>) {
std::cout << "non copy constructible";
}
void foo_bar(const T& v){
std::cout << "test";
}
};
int main(int argn, char** argc){
test<int> myfoo;
myfoo.foo(3); //Works
auto func = std::bind(&test<int>::foo_bar, &myfoo, 3); //Works
auto func2 = std::bind(&test<int>::foo, &myfoo, 3); //works
func();
func2();
}

Related

How to get a forwarding function to call a base template function that is declared after the forwarding function

I have a case where I need to have a forwarding function defined before a template base function is defined/declared. However, if I call the forwarding function (fwd) that in turn calls the base function test, it says that the base template function is not visible (see the code below). However, if test is called directly, everything works.
So my question is this, is it possible to have the forwarding function make a call to a base template function that is defined later in the compilation unit (before it is used but after the forwarding function)? If not, do I have any options to work around this? I would like to avoid a forward declaration before fwd as that would make use of the library I am developing harder. I think if I could force fwd to be inline it would solve the problem but I have no way of doing that unless a macro is used.
#include <iostream>
#include <vector>
template<typename T, std::enable_if_t<std::is_scalar<T>::value, int> = 0>
void test(const T& t)
{
std::cout << "Scalar" << std::endl;
}
template<typename T>
void fwd(T&& t)
{
test(std::forward<T>(t));
}
template<typename T>
void test(const std::vector<std::vector<T>>& t)
{
std::cout << "vector vector of T" << std::endl;
}
int main(int argc, const char * argv[]) {
test(1); //OK, prints Scalar
fwd(1); //OK, prints Scalar
test(std::vector<std::vector<int>>()); //OK, prints vector vector of T
// Causes compile error: Call to function 'test' that is neither visible in the template definition
// nor found by argument dependent lookup
fwd(std::vector<std::vector<int>>());
return 0;
}
The name test in fwd is a dependent name. It will be resolved into two steps:
Non-ADL lookup examines function declarations ... that are visible from the template definition context.
ADL examines function declarations ... that are visible from either the template definition context or the template instantiation context.
Given that the relative order of test and fwd should not be changed, one possible solution is to use a fake tag struct in the namespace to activate ADL:
namespace my_namespace
{
struct Tag {};
template<typename T, std::enable_if_t<std::is_scalar<T>::value, int> = 0>
void test(const T& t, Tag = Tag{}) {
std::cout << "Scalar" << std::endl;
}
template<typename T>
void fwd(T&& t) {
test(std::forward<T>(t), Tag{});
}
template<typename T>
void test(const std::vector<std::vector<T>>& t, Tag = Tag{}) {
std::cout << "vector vector of T" << std::endl;
}
}
int main() {
my_namespace::test(std::vector<std::vector<int>>()); // OK
my_namespace::fwd(std::vector<std::vector<int>>()); // OK, too
}
Demo
Depending on what test overloads you have, another solution might be to wrap these functions into structs and use template specialization instead of function overloading:
template<class T>
struct Test {
static void op(const T& t) {
std::cout << "Scalar" << std::endl;
}
};
template<typename T>
void fwd(T&& t) {
Test<std::decay_t<T>>::op(std::forward<T>(t));
}
template<class T>
struct Test<std::vector<std::vector<T>>> {
static void op(const std::vector<std::vector<T>>& t) {
std::cout << "vector vector of T" << std::endl;
}
};
int main() {
fwd(1);
fwd(std::vector<std::vector<int>>());
}
Demo

Overload resolution ambiguous [duplicate]

Consider this simple example code:
#include <functional>
#include <iostream>
void f(bool _switch) {
std::cout << "Nothing really" << std::endl;
}
void f(std::function<double (int)> _f) {
std::cout << "Nothing really, too" << std::endl;
}
int main ( int argc, char* argv[] ) {
f([](int _idx){ return 7.9;});
return 0;
}
It fails to compile:
$ g++ --std=c++11 main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:15:33: error: call of overloaded ‘f(main(int, char**)::<lambda(int)>)’ is ambiguous
main.cpp:15:33: note: candidates are:
main.cpp:6:6: note: void f(bool)
main.cpp:10:6: note: void f(std::function<double(int)>)
However if I replace the second function with a reference argument it compiles fine. And again if it is replaced by a const reference it fails.
So I have some questions concerning this example:
Why is a lambda function implicitly convertible to bool in the first place?
Why does taking a std::function reference solve the ambiguity?
And most important to me, how can I avoid this problem? I need the second function to take either a (copy of a) std::function or a const reference to it.
A lambda function with no capture can be converted to a regular function pointer, which then has a standard conversion to a bool.
If you take the std::function by non-const reference, then that eliminates it as a candidate, since converting the lambda to a std::function requires a temporary, and a temporary cannot bind to a non-const reference. That just leaves f(bool) as a candidate, so there is no ambiguity.
There are many ways you could avoid the ambiguity. For example, you could create a std::function variable first:
std::function<double(int)> g = [](int _idx){ return 7.9;};
f(g);
or you could cast the lambda:
f(std::function<double(int)>([](int _idx){return 7.9;}));
You could have a helper function:
template<typename T>
std::function<T> make_function(T *f) { return {f}; }
int main ( int argc, char* argv[] ) {
f(make_function([](int _idx){ return 7.9;}));
return 0;
}
or you could grab the particular function you are interested in:
int main ( int argc, char* argv[] ) {
void (*f_func)(std::function<double(int)>) = f;
f_func([](int _idx){ return 7.9;});
return 0;
}
namespace details{
template<class Sig,class=void>
struct invoke {};
template<class F, class...Args>
struct invoke<F(Args...),decltype(void(
std::declval<F>()(std::declval<Args>()...)
))>{
using type=decltype(std::declval<F>()(std::declval<Args>()...));
};
}
template<class Sig>struct invoke:details::invoke<Sig>{};
template<typename Sig, typename T, typename=void>
struct invoke_test:std::false_type {};
template<typename R, typename...Args, typename T>
struct invoke_test<R(Args...), T,
typename std::enable_if<
std::is_convertible<
typename invoke<T(Args...)>::type,
R
>::value
>::type
>:std::true_type {};
template<typename...Args,typename T>
struct invoke_test<void(Args...),T,
decltype( void( typename invoke<T(Args...)>::type ) )
>:std::true_type{};
template<typename Sig, typename T>
constexpr bool invokable() {
return invoke_test<Sig,T>::value;
}
this gives us a pseudo-concept invokable.
We can then use it like:
template<typename F>
typename std::enable_if<invokable<double(int),F>()>::type
f(F&&){
std::cout << "can be invoked\n";
}
void f(bool) {
std::cout << "is bool\n";
}
and bob is your uncle.
The real problem is that std::function<double(int)> 's constructor does not do a similar test, and instead claims (falsely) that it can be constructed from anything at all. This is a flaw in the standard, one I suspect will be fixed once concepts are standardized.
You can get rid of the implicit conversion by creating a helper class
#include <functional>
#include <iostream>
struct Boolean {
bool state;
Boolean(bool b):state(b){}
operator bool(){ return state; }
};
void f(Boolean _switch) {
std::cout << "Nothing really " << _switch << std::endl;
}
void f(std::function<double (int)> _f) {
std::cout << "Nothing really, too" << std::endl;
}
int main ( int argc, char* argv[] ) {
f([](int _idx){ return 7.9;});
f(true);
return 0;
}
Should you ever want to call f with eg. a pointer and expect it to call the first overload you will have to cast it to either bool or add a corresponding constructor / cast to the helper class though.
One more option to Vaughn Cato's answer:
template<typename F>
void f(F _f) {
std::cout << "Nothing really, too: " << _f(3) << std::endl;
}
Now the second overload is a template, so it is chosen for a lambda (or anything), and the first is chosen for bool. So calling f is no more complex than needed.
But, one problem with that is if you want to add more overloads, and another is that the first overload will only be called if there is an exact match to bool.

C++11 Lambda functions implicit conversion to bool vs. std::function

Consider this simple example code:
#include <functional>
#include <iostream>
void f(bool _switch) {
std::cout << "Nothing really" << std::endl;
}
void f(std::function<double (int)> _f) {
std::cout << "Nothing really, too" << std::endl;
}
int main ( int argc, char* argv[] ) {
f([](int _idx){ return 7.9;});
return 0;
}
It fails to compile:
$ g++ --std=c++11 main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:15:33: error: call of overloaded ‘f(main(int, char**)::<lambda(int)>)’ is ambiguous
main.cpp:15:33: note: candidates are:
main.cpp:6:6: note: void f(bool)
main.cpp:10:6: note: void f(std::function<double(int)>)
However if I replace the second function with a reference argument it compiles fine. And again if it is replaced by a const reference it fails.
So I have some questions concerning this example:
Why is a lambda function implicitly convertible to bool in the first place?
Why does taking a std::function reference solve the ambiguity?
And most important to me, how can I avoid this problem? I need the second function to take either a (copy of a) std::function or a const reference to it.
A lambda function with no capture can be converted to a regular function pointer, which then has a standard conversion to a bool.
If you take the std::function by non-const reference, then that eliminates it as a candidate, since converting the lambda to a std::function requires a temporary, and a temporary cannot bind to a non-const reference. That just leaves f(bool) as a candidate, so there is no ambiguity.
There are many ways you could avoid the ambiguity. For example, you could create a std::function variable first:
std::function<double(int)> g = [](int _idx){ return 7.9;};
f(g);
or you could cast the lambda:
f(std::function<double(int)>([](int _idx){return 7.9;}));
You could have a helper function:
template<typename T>
std::function<T> make_function(T *f) { return {f}; }
int main ( int argc, char* argv[] ) {
f(make_function([](int _idx){ return 7.9;}));
return 0;
}
or you could grab the particular function you are interested in:
int main ( int argc, char* argv[] ) {
void (*f_func)(std::function<double(int)>) = f;
f_func([](int _idx){ return 7.9;});
return 0;
}
namespace details{
template<class Sig,class=void>
struct invoke {};
template<class F, class...Args>
struct invoke<F(Args...),decltype(void(
std::declval<F>()(std::declval<Args>()...)
))>{
using type=decltype(std::declval<F>()(std::declval<Args>()...));
};
}
template<class Sig>struct invoke:details::invoke<Sig>{};
template<typename Sig, typename T, typename=void>
struct invoke_test:std::false_type {};
template<typename R, typename...Args, typename T>
struct invoke_test<R(Args...), T,
typename std::enable_if<
std::is_convertible<
typename invoke<T(Args...)>::type,
R
>::value
>::type
>:std::true_type {};
template<typename...Args,typename T>
struct invoke_test<void(Args...),T,
decltype( void( typename invoke<T(Args...)>::type ) )
>:std::true_type{};
template<typename Sig, typename T>
constexpr bool invokable() {
return invoke_test<Sig,T>::value;
}
this gives us a pseudo-concept invokable.
We can then use it like:
template<typename F>
typename std::enable_if<invokable<double(int),F>()>::type
f(F&&){
std::cout << "can be invoked\n";
}
void f(bool) {
std::cout << "is bool\n";
}
and bob is your uncle.
The real problem is that std::function<double(int)> 's constructor does not do a similar test, and instead claims (falsely) that it can be constructed from anything at all. This is a flaw in the standard, one I suspect will be fixed once concepts are standardized.
You can get rid of the implicit conversion by creating a helper class
#include <functional>
#include <iostream>
struct Boolean {
bool state;
Boolean(bool b):state(b){}
operator bool(){ return state; }
};
void f(Boolean _switch) {
std::cout << "Nothing really " << _switch << std::endl;
}
void f(std::function<double (int)> _f) {
std::cout << "Nothing really, too" << std::endl;
}
int main ( int argc, char* argv[] ) {
f([](int _idx){ return 7.9;});
f(true);
return 0;
}
Should you ever want to call f with eg. a pointer and expect it to call the first overload you will have to cast it to either bool or add a corresponding constructor / cast to the helper class though.
One more option to Vaughn Cato's answer:
template<typename F>
void f(F _f) {
std::cout << "Nothing really, too: " << _f(3) << std::endl;
}
Now the second overload is a template, so it is chosen for a lambda (or anything), and the first is chosen for bool. So calling f is no more complex than needed.
But, one problem with that is if you want to add more overloads, and another is that the first overload will only be called if there is an exact match to bool.

std::bind with template member function

I have a strange problem that I cannot bind this template member function,
all this code compiles: http://ideone.com/wl5hS8
It's a simple code: I have a ExecutionList which should hold callable functions in a std::vector. I can now add functions by calling ExecutionList::addFunctor. But there, I cannot bind to template<typename T> void Functor::calculate(T * t). I am asking me why, what is missing here, the compiler cannot somehow deduce what I have written in
m_calculationList.push_back( std::bind(&T::calculate<Type>, extForce, std::placeholders::_1 ) );
*Error: *
error: expected primary-expression before ‘>’ token
m_calculationList.push_back( std::bind(T::calculate<Type>, extForce, std::placeholders::_1 ) );
^
The Code:
#include <functional>
#include <iostream>
#include <vector>
struct MyType{
static int a;
int m_a;
MyType(){a++; m_a = a;}
void print(){
std::cout << "MyType: " << a << std::endl;
}
};
int MyType::a=0;
struct Functor{
static int a;
int m_a;
Functor(){a++; m_a = a;}
// Binding this function does not work
template<typename T>
void calculate(T * t){}
// Binding this function works!!!
void calculate2(MyType * t){
std::cout << " Functor: " << m_a <<std::endl;
t->print();
}
};
int Functor::a=0;
// Binding this function works!!!
template<typename T>
void foo( T * t){}
class ExecutionList{
public:
typedef MyType Type;
template<typename T>
void addFunctor(T * extForce){
//m_calculationList.push_back( std::bind(&T::calculate<Type>, extForce, std::placeholders::_1 ) ); /// THIS DOES NOT WORK
m_calculationList.push_back( std::bind(&T::calculate2, extForce, std::placeholders::_1 ) );
m_calculationList.push_back( std::bind(&foo<Type>, std::placeholders::_1 ) );
}
void calculate(Type * t){
for(auto it = m_calculationList.begin(); it != m_calculationList.end();it++){
(*it)(t); // Apply calculation function!
}
}
private:
std::vector< std::function<void (Type *)> > m_calculationList;
};
int main(){
MyType b;
ExecutionList list;
list.addFunctor(new Functor());
list.addFunctor(new Functor());
list.calculate(&b);
}
Looks like you're missing the template keyword. If T is a template parameter and T::calculate refers to a template you need to tell the compiler that calculate is a template and not some static variable which you try to compare using the less-than operator with something else:
T::template calculate<Type>
I ran into the exact same problem a couple of years ago but today (post C++11) I would probably solve it with a lambda which is simpler:
std::function<void(Type*)> func = [obj](Type*param){obj.calculate(param);};
Anyhow, try to reduce the number of new uses. Look for a better way to manage your resources. Your code seems to leak a couple of functors.

How do I avoid implicit conversions on non-constructing functions?

How do I avoid implicit casting on non-constructing functions?
I have a function that takes an integer as a parameter,
but that function will also take characters, bools, and longs.
I believe it does this by implicitly casting them.
How can I avoid this so that the function only accepts parameters of a matching type, and will refuse to compile otherwise?
There is a keyword "explicit" but it does not work on non-constructing functions. :\
what do I do?
The following program compiles, although I'd like it not to:
#include <cstdlib>
//the function signature requires an int
void function(int i);
int main(){
int i{5};
function(i); //<- this is acceptable
char c{'a'};
function(c); //<- I would NOT like this to compile
return EXIT_SUCCESS;
}
void function(int i){return;}
*please be sure to point out any misuse of terminology and assumptions
Define function template which matches all other types:
void function(int); // this will be selected for int only
template <class T>
void function(T) = delete; // C++11
This is because non-template functions with direct matching are always considered first. Then the function template with direct match are considered - so never function<int> will be used. But for anything else, like char, function<char> will be used - and this gives your compilation errrors:
void function(int) {}
template <class T>
void function(T) = delete; // C++11
int main() {
function(1);
function(char(1)); // line 12
}
ERRORS:
prog.cpp: In function 'int main()':
prog.cpp:4:6: error: deleted function 'void function(T) [with T = char]'
prog.cpp:12:20: error: used here
This is C++03 way:
// because this ugly code will give you compilation error for all other types
class DeleteOverload
{
private:
DeleteOverload(void*);
};
template <class T>
void function(T a, DeleteOverload = 0);
void function(int a)
{}
You can't directly, because a char automatically gets promoted to int.
You can resort to a trick though: create a function that takes a char as parameter and don't implement it. It will compile, but you'll get a linker error:
void function(int i)
{
}
void function(char i);
//or, in C++11
void function(char i) = delete;
Calling the function with a char parameter will break the build.
See http://ideone.com/2SRdM
Terminology: non-construcing functions? Do you mean a function that is not a constructor?
8 years later (PRE-C++20, see edit):
The most modern solution, if you don't mind template functions -which you may mind-, is to use a templated function with std::enable_if and std::is_same.
Namely:
// Where we want to only take int
template <class T, std::enable_if_t<std::is_same_v<T,int>,bool> = false>
void func(T x) {
}
EDIT (c++20)
I've recently switched to c++20 and I believe that there is a better way. If your team or you don't use c++20, or are not familiar with the new concepts library, do not use this. This is much nicer and the intended method as outlines in the new c++20 standard, and by the writers of the new feature (read a papers written by Bjarne Stroustrup here.
template <class T>
requires std::same_as(T,int)
void func(T x) {
//...
}
Small Edit (different pattern for concepts)
The following is a much better way, because it explains your reason, to have an explicit int. If you are doing this frequently, and would like a good pattern, I would do the following:
template <class T>
concept explicit_int = std::same_as<T,int>;
template <explicit_int T>
void func(T x) {
}
Small edit 2 (the last I promise)
Also a way to accomplish this possibility:
template <class T>
concept explicit_int = std::same_as<T,int>;
void func(explicit_int auto x) {
}
Here's a general solution that causes an error at compile time if function is called with anything but an int
template <typename T>
struct is_int { static const bool value = false; };
template <>
struct is_int<int> { static const bool value = true; };
template <typename T>
void function(T i) {
static_assert(is_int<T>::value, "argument is not int");
return;
}
int main() {
int i = 5;
char c = 'a';
function(i);
//function(c);
return 0;
}
It works by allowing any type for the argument to function but using is_int as a type-level predicate. The generic implementation of is_int has a false value but the explicit specialization for the int type has value true so that the static assert guarantees that the argument has exactly type int otherwise there is a compile error.
Maybe you can use a struct to make the second function private:
#include <cstdlib>
struct NoCast {
static void function(int i);
private:
static void function(char c);
};
int main(){
int i(5);
NoCast::function(i); //<- this is acceptable
char c('a');
NoCast::function(c); //<- Error
return EXIT_SUCCESS;
}
void NoCast::function(int i){return;}
This won't compile:
prog.cpp: In function ‘int main()’:
prog.cpp:7: error: ‘static void NoCast::function(char)’ is private
prog.cpp:16: error: within this context
For C++14 (and I believe C++11), you can disable copy constructors by overloading rvalue-references as well:
Example:
Say you have a base Binding<C> class, where C is either the base Constraint class, or an inherited class. Say you are storing Binding<C> by value in a vector, and you pass a reference to the binding and you wish to ensure that you do not cause an implicit copy.
You may do so by deleting func(Binding<C>&& x) (per PiotrNycz's example) for rvalue-reference specific cases.
Snippet:
template<typename T>
void overload_info(const T& x) {
cout << "overload: " << "const " << name_trait<T>::name() << "&" << endl;
}
template<typename T>
void overload_info(T&& x) {
cout << "overload: " << name_trait<T>::name() << "&&" << endl;
}
template<typename T>
void disable_implicit_copy(T&& x) = delete;
template<typename T>
void disable_implicit_copy(const T& x) {
cout << "[valid] ";
overload_info<T>(x);
}
...
int main() {
Constraint c;
LinearConstraint lc(1);
Binding<Constraint> bc(&c, {});
Binding<LinearConstraint> blc(&lc, {});
CALL(overload_info<Binding<Constraint>>(bc));
CALL(overload_info<Binding<LinearConstraint>>(blc));
CALL(overload_info<Binding<Constraint>>(blc));
CALL(disable_implicit_copy<Binding<Constraint>>(bc));
// // Causes desired error
// CALL(disable_implicit_copy<Binding<Constraint>>(blc));
}
Output:
>>> overload_info(bc)
overload: T&&
>>> overload_info<Binding<Constraint>>(bc)
overload: const Binding<Constraint>&
>>> overload_info<Binding<LinearConstraint>>(blc)
overload: const Binding<LinearConstraint>&
>>> overload_info<Binding<Constraint>>(blc)
implicit copy: Binding<LinearConstraint> -> Binding<Constraint>
overload: Binding<Constraint>&&
>>> disable_implicit_copy<Binding<Constraint>>(bc)
[valid] overload: const Binding<Constraint>&
Error (with clang-3.9 in bazel, when offending line is uncommented):
cpp_quick/prevent_implicit_conversion.cc:116:8: error: call to deleted function 'disable_implicit_copy'
CALL(disable_implicit_copy<Binding<Constraint>>(blc));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Full Source Code: prevent_implicit_conversion.cc
Well, I was going to answer this with the code below, but even though it works with Visual C++, in the sense of producing the desired compilation error, MinGW g++ 4.7.1 accepts it, and invokes the rvalue reference constructor!
I think it must be a compiler bug, but I could be wrong, so – anyone?
Anyway, here's the code, which may turn out to be a standard-compliant solution (or, it may turn out that that's a thinko on my part!):
#include <iostream>
#include <utility> // std::is_same, std::enable_if
using namespace std;
template< class Type >
struct Boxed
{
Type value;
template< class Arg >
Boxed(
Arg const& v,
typename enable_if< is_same< Type, Arg >::value, Arg >::type* = 0
)
: value( v )
{
wcout << "Generic!" << endl;
}
Boxed( Type&& v ): value( move( v ) )
{
wcout << "Rvalue!" << endl;
}
};
void function( Boxed< int > v ) {}
int main()
{
int i = 5;
function( i ); //<- this is acceptable
char c = 'a';
function( c ); //<- I would NOT like this to compile
}
I first tried PiotrNycz's approach (for C++03, which I'm forced to use for a project), then I tried to find a more general approach and came up with this ForcedType<T> template class.
template <typename T>
struct ForcedType {
ForcedType(T v): m_v(v) {}
operator T&() { return m_v; }
operator const T&() const { return m_v; }
private:
template <typename T2>
ForcedType(T2);
T m_v;
};
template <typename T>
struct ForcedType<const T&> {
ForcedType(const T& v): m_v(v) {}
operator const T&() const { return m_v; }
private:
template <typename T2>
ForcedType(const T2&);
const T& m_v;
};
template <typename T>
struct ForcedType<T&> {
ForcedType(T& v): m_v(v) {}
operator T&() { return m_v; }
operator const T&() const { return m_v; }
private:
template <typename T2>
ForcedType(T2&);
T& m_v;
};
If I'm not mistaken, those three specializations should cover all common use cases. I'm not sure if a specialization for rvalue-reference (on C++11 onwards) is actually needed or the by-value one suffices.
One would use it like this, in case of a function with 3 parameters whose 3rd parameter doesn't allow implicit conversions:
function(ParamType1 param1, ParamType2 param2, ForcedType<ParamType3> param3);