Как я могу отличить перегрузки шаблонов с нетиповыми параметрами?

Вот две функции шаблона, которые отличаются только параметрами своего шаблона. Остальные параметры точно такие же.

    template
    void template_const(int &a,int & b){
            a = a & module;
            b = b % module;
    }

    template
    void template_const(int &a,int & b){
            int w;
            if (x){
                    w = 123;
            }
            else w = 512;
            a = a & w;
            b = b % w;
    }

Когда я пытаюсь назвать их так

template_const(a,b)

или же

template_const(a,b)

компилятор говорит мне, что вызов неоднозначен. Как я могу вызвать эти две функции?

Ответы на вопрос(2)

Решение Вопроса

проблема в том, что компилятор не может упорядочить эти две функции, т. Е. Нет одной, более специализированной, чем другая. Как объяснено в §14.5.6.2, когда вызов шаблона перегруженной функции неоднозначен, компилятор использует частичное упорядочение между различными перегрузками, чтобы выбрать наиболее специализированную.

Чтобы упорядочить перегрузки, компилятор преобразует каждую из них и выполняет вывод аргумента шаблона, чтобы увидеть, является ли один более специализированным, чем другой (в конце приведено краткое объяснениеэтот ответ). В вашем случае две перегрузки эквивалентны (или не сопоставимы):template void template_const(int &,int &) не более специализирован, чемtemplate void template_const(int &, int &), и наоборот.

Таким образом, компилятор не может выбрать один над другим, следовательно, генерируетambiguous call ошибка.

Если вы согласны с точным указанием типа параметра, который вы хотите передать, вы можете использовать частичную специализацию шаблона следующим образом:

template<typename t,="" t="" param="">
struct template_const_impl;

template <int module="">
struct template_const_impl<int, module="">
{
    static void apply(int &a, int &b)
    {
        a = a & module;
        b = b % module;
    }
};

template<bool x="">
struct template_const_impl<bool, x="">
{
    static void apply(int &a, int &b)
    {
        const int w = x ? 123 : 512;
        a = a & w;
        b = b % w;
    }
};

template <typename t,="" t="" param="">
void template_const(int &a, int &b)
{
    return template_const_impl<t, param="">::apply(a, b);
}

int main()
{
    int i = 512, j = 256;
    template_const<int, 123="">(i, j);
    template_const<bool, true="">(i, j);
}
</bool,></int,></t,></typename></bool,></bool></int,></int></typename>

Это не идеально, но это неЯ думаю, что есть более чистое решение, если вы не можете использовать C ++ 11 и не хотите полагаться на некоторые макросы, и в этом случае вы можете немного упростить вызывающий код (идея взята из @Nawaz вэтот ответ):

#define TEMPLATE_CONST(x) template_const<decltype(x), x="">

int main()
{
    int i = 512, j = 256;
    TEMPLATE_CONST(123)(i, j);
    TEMPLATE_CONST(true)(i, j);
}
</decltype(x),>

что это будет работать так. У вас есть перегрузки с одинаковыми типами параметров. Возможно, вам придется дать им разные имена в конце и назвать их, как вы пытались.

 worldterminator26 июн. 2013 г., 09:25
Но они прошли сборник. Шаблон компилируется, когда они на самом деле вызываются?
 Slava26 июн. 2013 г., 09:41
Компилятор говорит, что вызов неоднозначен, верно? что не называется передал компиляцию. Конечно, все компилируется во время компиляции, шаблоны компилируются только тогда, когда запрашивается инстанцирование.
 jogojapan26 июн. 2013 г., 10:05
Это'Правда, это не сработает. Но проблема не просто в том, что типы параметров функции одинаковы. Вы можете перегрузить шаблон функции, просто изменив параметр шаблона (а не типы аргументов функции). Проблема в том, что механизм устранения неоднозначности, используемый при разрешении перегрузки шаблона, учитываетbool а такжеint как равный (в отличие от механизма разрешения, используемого для обычных аргументов функции).

Ваш ответ на вопрос