У меня есть следующий фрагмент кода, который имеет две версии функции foo. Я хотел бы, чтобы переменная передавалась для foo, который принимает тип AVar для вызова в противном случае, если const передается для вызова версии AConst.
#include <iostream>
template <typename T>
struct AConst
{
AConst(T x):t(x){}
const T t;
};
template <typename T>
struct AVar
{
AVar(const T& x):t(x){}
const T& t;
};
template <typename T>
void foo(AConst<T> a) { std::cout << "foo AConst\n"; }
template <typename T>
void foo(AVar<T> a) { std::cout << "foo AVar\n"; }
int main()
{
int i = 2;
foo(1);
foo(i);
return 0;
}
В настоящее время компилятор выдает ошибку неоднозначности. Не уверен, как решить это.
ОБНОВИТЬ: Основываясь на ответе Леонида с небольшой модификацией, вот следующее решение, которое работает как требуется:
template <typename T>
void foo_x(AConst<T> a) { std::cout << "foo AConst\n"; }
template <typename T>
void foo_x(AVar<T> a) { std::cout << "foo AVar\n"; }template <typename T>
void foo(const T& a) { foo_x(AConst<T>(a));}
template <typename T>
void foo(T& a) { foo_x(AVar<T>(a));}
Компилятор не может вывести ваш T.
Чтобы помочь ему, упростите тип параметра:
template <typename T>
void foo(const T& a) { AConst<T> aa(a); std::cout << "foo AConst\n"; }
template <typename T>
void foo(T& a) { AVar<T> aa(a); std::cout << "foo AVar\n"; }
Используйте приведение, чтобы устранить ошибки неоднозначности. В этом случае вы можете разыграть «1» как AConst, если я правильно помню. Я не помню точный синтаксис приведения к типу шаблона … может быть, что-то вроде:
foo( (AConst<int>) 1); .. or something to that effect.
Компилятор не может выбрать соответствующую функцию. Вы можете объявить 2 функции с разными именами:
template <typename T>
void fooConst(AConst<T> a) { std::cout << "foo AConst\n"; }
template <typename T>
void fooVar(AVar<T> a) { std::cout << "foo AVar\n"; }
Или вы можете использовать следующие функции:
int main()
{
int i = 2;
foo(AConst<int>(1));
foo(AVar<int>(i));
return 0;
}
В общем, вы не предоставляете достаточно информации компилятору. Вы единственный, кто знает, какой экземпляр следует использовать в основной функции. Возможно, если бы вы описали более подробно, какова цель этого кода, решение было бы более конкретным.
Вы можете передать полный шаблон класса в функцию следующим образом
#include <iostream>
template <typename T>
struct AConst
{
AConst(T x) :t(x){ std::cout << "AConst\n"; }
const T t;
};
template <typename T>
struct AVar
{
AVar(const T& x) :t(x){ std::cout << "AVar\n"; }
const T& t;
};
template <typename T1>
void foo(T1 a){}
int main()
{
int i = 2;
foo<AConst<int>>(1);
foo<AVar<int>>(i);
return 0;
}