Поделиться через


Ошибка компилятора C2059

синтаксическая ошибка: "token"

Маркер вызвал ошибку синтаксиса.

В следующем примере создается сообщение об ошибке для строки, объявляющей j.

// C2059e.cpp
// compile with: /c
// C2143 expected
// Error caused by the incorrect use of '*'.
   int j*; // C2059

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

Если сообщение об ошибке возникает typedef на символе, который сразу же следует переменной, убедитесь, что переменная определена в исходном коде.

C2059 возникает при повторном использовании имени символа препроцессора в качестве идентификатора. В следующем примере компилятор видит DIGITS.ONE номер 1, который не является допустимым в качестве имени элемента перечисления:

#define ONE 1

enum class DIGITS {
    ZERO,
    ONE // error C2059
};

Вы можете получить C2059, если символ не оценивается ничего, как это может произойти, когда символ /D= используется для компиляции.

// C2059a.cpp
// compile with: /DTEST=
#include <stdio.h>

int main() {
   #ifdef TEST
      printf_s("\nTEST defined %d", TEST);   // C2059
   #else
      printf_s("\nTEST not defined");
   #endif
}

Другой случай, в котором может произойти C2059, заключается в компиляции приложения, указывающего структуру в аргументах по умолчанию для функции. Значение по умолчанию для аргумента должно быть выражением. Например, список инициализаторов, используемый для инициализации структуры, не является выражением. Чтобы устранить эту проблему, определите конструктор для выполнения требуемой инициализации.

В следующем примере создается C2059:

// C2059b.cpp
// compile with: /c
struct ag_type {
   int a;
   float b;
   // Uncomment the following line to resolve.
   // ag_type(int aa, float bb) : a(aa), b(bb) {}
};

void func(ag_type arg = {5, 7.0});   // C2059
void func(ag_type arg = ag_type(5, 7.0));   // OK

C2059 может возникать для плохо сформированного приведения.

Следующий пример приводит к возникновению ошибки C2059:

// C2059c.cpp
// compile with: /clr
using namespace System;
ref class From {};
ref class To : public From {};

int main() {
   From^ refbase = gcnew To();
   To^ refTo = safe_cast<To^>(From^);   // C2059
   To^ refTo2 = safe_cast<To^>(refbase);   // OK
}

C2059 также может возникать при попытке создать имя пространства имен, содержащее период.

Следующий пример приводит к возникновению ошибки C2059:

// C2059d.cpp
// compile with: /c
namespace A.B {}   // C2059

// OK
namespace A  {
   namespace B {}
}

C2059 может возникать, когда оператор, который может квалифицировать имя (::, ->и .) должен следовать ключевому слову template, как показано в этом примере:

template <typename T> struct Allocator {
    template <typename U> struct Rebind {
        typedef Allocator<U> Other;
    };
};

template <typename X, typename AY> struct Container {
    typedef typename AY::Rebind<X>::Other AX; // error C2059
};

По умолчанию C++ предполагает, что AY::Rebind не является шаблоном. Поэтому следующее < интерпретируется как знак меньшего значения. Компилятор должен явно сообщить компилятору, что Rebind является шаблоном, чтобы он смог правильно проанализировать угловую скобку. Чтобы исправить эту ошибку, используйте ключевое template слово в имени зависимого типа, как показано ниже:

template <typename T> struct Allocator {
    template <typename U> struct Rebind {
        typedef Allocator<U> Other;
    };
};

template <typename X, typename AY> struct Container {
    typedef typename AY::template Rebind<X>::Other AX; // correct
};