Почему этот код компилируется с g ++, но не с MSVC ++? - PullRequest
5 голосов
/ 04 июля 2019

Я пытаюсь скомпилировать некоторый код с открытым исходным кодом (https://github.com/BieremaBoyzProgramming/bbpPairings),), который я могу получить для компиляции в Linux, используя g++ (v6.3.0), но не удается скомпилировать в Visual Studio (VS Community2019 / 16.1.5), с несколько неясной (для меня, но мой C ++, по общему признанию, слабой) ошибкой: "ошибка C2143: синтаксическая ошибка: отсутствует"; "перед" <"". </p>

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

#include <iostream>
#include <random>

class Configuration {};

class MatchesConfiguration {
public:
    template <class RandomEngine>
    MatchesConfiguration(
        Configuration&&,
        RandomEngine&);
};

template <class RandomEngine>
MatchesConfiguration::MatchesConfiguration(
    Configuration&& configuration,
    RandomEngine& randomEngine) {}

template
MatchesConfiguration::MatchesConfiguration<std::minstd_rand>( // <--- SYNTAX ERROR HERE
    Configuration&&,
    std::minstd_rand&);

int main()
{
    std::cout << "Hello World!\n"; 
}

Я посмотрел на MSDN описание кода ошибки , но мое понимание C ++ и шаблонов слишком слабое, чтобы понять, что происходит не так. Проект README говорит, что C ++ 14 ожидаем (с некоторыми дополнительными C ++ 17 вещами для FS, которые здесь не имеют значения, я думаю), но, насколько я понимаю, из таблицы совместимости функций все C ++ 14 должны поддерживаться VS 2019.

1 Ответ

5 голосов
/ 04 июля 2019

Когда вы предоставляете явное определение экземпляра конструктора (который на самом деле не имеет имени в соответствии со стандартом), вы должны сделать это, предоставив подпись, которую вынравится создавать, например, так:

template
MatchesConfiguration::MatchesConfiguration(  // no <std::minstd_rand> here
    Configuration&&,
    std::minstd_rand&);

[ temp.arg.explicit # 2 ]

Аргументы шаблона не должны указываться при обращении кспециализация шаблона конструктора


Общая информация из старой заметки (с 2006 года):
http://www.open -std.org / jtc1 / sc22 / wg21 / docs / cwg_active.html # 581

" Может ли шаблонный конструктор быть явно создан или специализирован? "

невозможно указать аргументы шаблона конструкторав вызове конструктора (поскольку конструктор не имеет имени, но вызывается с использованием имени класса конструктора)

[...]

Было замечено, что явное указание аргументов шаблона вобъявление конструктора никогда не выполняетсяy необходимо, потому что аргументы по определению все выводимы и, следовательно, могут быть опущены.

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

Спасибо Дэвису Херрингу и ММ за руководство

...