1

I am getting following errors when trying to compile a c++ file in Visual Studio 2019. The developer who built the software says this used to work on Visual Studio 2012.

I get the following error:

Severity    Code    Description Project File    Line    Suppression State
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 45  
Error   C3699   '^': cannot use this indirection on type 'std::array'   CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 45  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 45  
Error   C2027   use of undefined type 'std::array'  CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 45  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 46  
Error   C3699   '^': cannot use this indirection on type 'std::array'   CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 46  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 46  
Error   C2027   use of undefined type 'std::array'  CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 46  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 47  
Error   C3699   '^': cannot use this indirection on type 'std::array'   CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 47  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 47  
Error   C2027   use of undefined type 'std::array'  CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 47  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 49  
Error   C3699   '^': cannot use this indirection on type 'std::array'   CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 49  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 49  
Error   C2027   use of undefined type 'std::array'  CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 49  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 50  
Error   C3699   '^': cannot use this indirection on type 'std::array'   CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 50  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 50  
Error   C2027   use of undefined type 'std::array'  CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 50  
Error   C2582   'operator =' function is unavailable in 'std::array'    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 52  
Error   C2582   'operator =' function is unavailable in 'std::array'    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 53  
Error   C2582   'operator =' function is unavailable in 'std::array'    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 54  
Error C2664 'void CalculatorLibrary::ExternalInterface::AddHubInformationv                    (int,cli::array<double,1> ^,cli::array<System::String ^,1> ^,cli::array<System::String ^,1> ^)': cannot  convert argument 2 from 'std::array *' to 'cli::array<double,1> ^'   CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 57  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 76  
Error   C3699   '^': cannot use this indirection on type 'std::array'   CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 76  
Error   C2976   'std::array': too few template arguments    CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\CalculatorsAIMMSInterop.cpp 76  

Here is the code which is failing:

#include "stdafx.h"
#include <msclr/marshal.h>
#include "CalculatorsAIMMSInterop.h"

using namespace msclr::interop;
using namespace System;
using namespace System::Reflection;
using namespace std;

void marshalString(System::String^ input, char* output)
{
    //marshal_context ^ context = MarshalContextSingleton::GetInstance();
    marshal_context ^ context = gcnew marshal_context();
    const char* strResult = context->marshal_as<const char*>(input);
    strcpy(output, strResult);
    delete context;
}

void marshalInt(System::Int32 input, char* output) 
{
    //marshal_context ^ context = MarshalContextSingleton::GetInstance();
    marshal_context ^ context = gcnew marshal_context();
    const char* strResult = context->marshal_as<const char*> (""+input);
    strcpy(output, strResult);
    delete context;
}

System::String^ marshalString(char* input)
{
    //marshal_context ^ context = MarshalContextSingleton::GetInstance();
    marshal_context ^ context = gcnew marshal_context();
    System::String^ output = context->marshal_as<System::String^>(input);
    delete context;
    return output;
}

// Methods for hub activity calculator
void WINAPI HubActivityInitialize(int calenderStart, int calendarEnd) {
    CalculatorLibrary::ExternalInterface::InitializeHubActivityCalculator(calenderStart, calendarEnd);
}

void WINAPI HubActivityAddInformation(int numberOfValues, double* activities, char** arrivalTimes, char** departureTimes) {
    array<double>^ activitiesDoubles = gcnew array<double>(numberOfValues);
    array<String^>^ arrivalTimeStrs = gcnew array<String^>(numberOfValues);
    array<String^>^ departureTimeStrs = gcnew array<String^>(numberOfValues);

    array<int>^ arrivalTimeInts = gcnew array<int>(numberOfValues);
    array<int>^ departureTimeInts = gcnew array<int>(numberOfValues);
    for (int i = 0; i < numberOfValues; i++) {
        activitiesDoubles[i] = activities[i];
        arrivalTimeStrs[i] = marshalString(arrivalTimes[i]);
        departureTimeStrs[i] = marshalString(departureTimes[i]);
    }

    CalculatorLibrary::ExternalInterface::AddHubInformation(numberOfValues, activitiesDoubles, arrivalTimeStrs, departureTimeStrs);
}

void WINAPI HubActivityGet(double* amounts) {
    System::Collections::Generic::List<double>^ hubActivityAmounts = CalculatorLibrary::ExternalInterface::GetHubActivity();
    for(int i = 0; i < hubActivityAmounts->Count; i++ )
    {
        amounts[i] = hubActivityAmounts[i];
    }
}

void WINAPI HubActivityReset() {
    CalculatorLibrary::ExternalInterface::ResetHubActivity();
}

// Methods for conveying calculator
void WINAPI ConveyingInitialize(int start, int end, char** startedConveyingQuantity) {
    int numberOfValues = end - start + 1;

    array<String^>^ quantity = gcnew array<String^>(numberOfValues);
    for (int i = 0; i < numberOfValues; i++) {
        quantity[i] = marshalString(startedConveyingQuantity[i]);
    }

    CalculatorLibrary::ExternalInterface::InitializeConveyingCalculator(start, end, quantity);
}

void WINAPI ConveyingAddPieceInformation(int numberOfPieces, char** inMovementsIds) {
    array<String^>^ incomingMovementIds = gcnew array<String^>(numberOfPieces);

    for (int i = 0; i < numberOfPieces; i++) {
        incomingMovementIds[i] = marshalString(inMovementsIds[i]);
    }

    CalculatorLibrary::ExternalInterface::AddConveyingPieceInformation(numberOfPieces, incomingMovementIds);
}

void WINAPI ConveyingAddConnectionInformation(int numberOfConnections, char** inMovementsIds, char** outMovementsIds, char** numberOfConnectedPieces) {
    array<String^>^ incomingMovementIds = gcnew array<String^>(numberOfConnections);
    array<String^>^ outgoingMovementIds = gcnew array<String^>(numberOfConnections);
    array<String^>^ connectedPieces = gcnew array<String^>(numberOfConnections);

    for (int i = 0; i < numberOfConnections; i++) {
        incomingMovementIds[i] = marshalString(inMovementsIds[i]);
        outgoingMovementIds[i] = marshalString(outMovementsIds[i]);
        connectedPieces[i] = marshalString(numberOfConnectedPieces[i]);
    }

    CalculatorLibrary::ExternalInterface::AddConveyingConnectionInformation(incomingMovementIds, outgoingMovementIds, connectedPieces);
}

void WINAPI ConveyingRunCalculation() {
    CalculatorLibrary::ExternalInterface::RunConveyingCalculation();
}

void WINAPI ConveyingResultGet(char** pieceMovementIDOut, char** pieceTimeAtConveyor) {
    array<int>^ pieceOutgoingMovement = CalculatorLibrary::ExternalInterface::GetPieceOutgoingMovement();
    array<int>^ pieceConveyorEntryTime = CalculatorLibrary::ExternalInterface::GetPieceConveyorEntryTime();

    for(int i = 0; i < pieceOutgoingMovement->Length; i++ )
    {
        marshalInt(pieceOutgoingMovement[i], pieceMovementIDOut[i]);
        marshalInt(pieceConveyorEntryTime[i], pieceTimeAtConveyor[i]);
    }
}

void WINAPI ConveyingReset() {
    CalculatorLibrary::ExternalInterface::ResetConveying();
}

// Methods for conveying calculator via text files
void WINAPI ConveyingInitializeFromFile(char* filePath) {
    String^ path = marshalString(filePath);
    CalculatorLibrary::ExternalInterface::InitializeConveyingCalculator(path);
}

void WINAPI WriteConveyingCalculationToFile(char* filePath) {
    String^ path = marshalString(filePath);
    CalculatorLibrary::ExternalInterface::WriteConveyingCalculatorData(path);
}

// Methods for Route Generation
void WINAPI InitializeCaseWithLogging(char* logfile_name) {
    RouteGeneration::IO::ExternalInterface::Initialize(marshalString(logfile_name));
}

int WINAPI GetRouteGenerationInputErrorCount() {
    return RouteGeneration::IO::ExternalInterface::CloseErrorLogAndRetrieveErrorCount();
}

void WINAPI RouteGenerationInitializeFromFiles(char* filePath1, char* filePath2, char* errorMessage) {
    String^ path1 = marshalString(filePath1);
    String^ message1 = RouteGeneration::IO::ExternalInterface::ReadNetworkModelInformation(path1);

    if (message1 != "OK") {
        marshalString(message1, errorMessage);
        return;
    }

    String^ path2 = marshalString(filePath2);
    String^ message2 = RouteGeneration::IO::ExternalInterface::ReadRouteGenerationRequests(path2);

    marshalString(message2, errorMessage);
}

void WINAPI RunRouteGeneration() {
    RouteGeneration::IO::ExternalInterface::GenerateRoutes();
}

void WINAPI RunAllToAllRouteGeneration(char* modelDataFilePath, char* requestDataFilePath, char* databaseFilePath, char* errorMessage) {
    String^ modelDataPath = marshalString(modelDataFilePath);
    String^ requestDataPath = marshalString(requestDataFilePath);
    String^ databasePath = marshalString(databaseFilePath);

    String^ message = RouteGeneration::IO::ExternalInterface::ReadAndGenerateAllToAllRoutes(modelDataPath, requestDataPath, databasePath);
    marshalString(message, errorMessage);
}

void WINAPI WriteGeneratedRoutesToFile(char* filePath, char* errorMessage) {
    String^ path = marshalString(filePath);
    String^ message = RouteGeneration::IO::ExternalInterface::WriteGeneratedRoutes(path);

    marshalString(message, errorMessage);
}

void WINAPI RouteGenerationReset() {
    RouteGeneration::IO::ExternalInterface::CleanMemory();
}

// Methods for Hub Simulation
void WINAPI InitializeSimulationCaseWithLogging(char* logfile_name) {
    HubSimulation::IO::ExternalInterface::Initialize(marshalString(logfile_name));
}

int WINAPI GetHubSimulationInputErrorCount() {
    return HubSimulation::IO::ExternalInterface::CloseErrorLogAndRetrieveErrorCount();
}

void WINAPI HubSimulationInitializeFromFiles(char* filePath1, char* filePath2, char* errorMessage) {
    String^ path1 = marshalString(filePath1);
    String^ message1 = HubSimulation::IO::ExternalInterface::ReadHubSimulationModelInformation(path1);

    if (message1 != "OK") {
        marshalString(message1, errorMessage);
        return;
    }

    String^ path2 = marshalString(filePath2);
    String^ message2 = HubSimulation::IO::ExternalInterface::ReadPiecesInformation(path2);

    marshalString(message2, errorMessage);
}

void WINAPI RunHubSimulation() {
    HubSimulation::IO::ExternalInterface::RunSimulation();
}

void WINAPI WriteHubSimulationResultsToFile(char* filePath, char* errorMessage) {
    String^ path = marshalString(filePath);

    String^ message = HubSimulation::IO::ExternalInterface::WriteSimulationResults(path);
    marshalString(message, errorMessage);
}

void WINAPI HubSimulationReset() {
    HubSimulation::IO::ExternalInterface::CleanMemory();
}
Doron Yakovlev Golani
  • 5,188
  • 9
  • 36
  • 60
  • It would help us if you show some lines of code (a MWE) that VS cannot compile – Damien Feb 05 '20 at 13:19
  • If the code has `std::array` I would think a newer compiler would be a better choice. With that said I see the code is `c++-cli` – drescherjm Feb 05 '20 at 13:26
  • 3
    `array^` does not look like `std::array`. I think this bug is caused by `using namespace std;` [https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – drescherjm Feb 05 '20 at 14:12
  • I am using Visual Studio Community Edition 2019 –  Feb 05 '20 at 14:21
  • 1
    Try removing `using namespace std;` and fix the errors created by that. – drescherjm Feb 05 '20 at 14:26
  • It keeps yelling as follows: Severity Code Description Project File Line Suppression State Error C1083 Cannot open source file: 'C:\WINDOWS\TEMP\.NETFramework,Version=v4.5.AssemblyAttributes.cpp': No such file or directory –  Feb 05 '20 at 14:29

2 Answers2

1

Why there is no Visual Studio Express 2012 available to download?

There is. Googling "visual studio express 2012 download" takes you straight to https://visualstudio.microsoft.com/vs/older-downloads from which you may download the application.


That being said, it's likely that installing this particular software won't fix your problem. You haven't shown us the code, or told us which compiler you're using (clearly it's not Visual Studio 2012; is it older? newer?). But it seems unlikely for a "too few template arguments" error from std::array to be fixed by a version change.

The error suggests a std::array * is being passed; this is a thing that does not exist. There is no type std::array; there are only template specialisations like std::array<T, N>.

You should ask the author for clarification because this seems like a code bug. Then, opt to use the most recent Visual Studio, instead of outdated software.


Also C# is something else. Presumably the project contains C#, and then this C++/CLI code as an interop layer. But the C# is unrelated to your question and to your problem.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • Many thanks Asteroids with Wings. I tried to download from the very same page but it links me to a log-in page and after I log in, it says there is nothin to download!! very weird. –  Feb 05 '20 at 13:47
  • @AlirezaAsadi: Seriously dude, just fix the code. If you can isolate it down to a few lines then we can suggest a fix. It might be as simple as putting `#include ` in your precompiled header. – Bathsheba Feb 05 '20 at 13:48
  • As to the Code, indeed the main code is C# but a C++/CLI layer is used as a transition layer which is causing trouble. The C# part are compiled flawless, However, in C++ part, there is an external dependency called AssemblyInfo.cpp which gives the following error: Severity Code Description Project File Line Suppression State Error C1083 Cannot open source file: 'C:\WINDOWS\TEMP\.NETFramework,Version=v4.5.AssemblyAttributes.cpp': No such file or directory CalculatorsAIMMSInterop C:\DELTA\NDHCalculators\Development\CalculatorsAIMMSInterop\c1xx 1 –  Feb 05 '20 at 13:50
  • @Bathsheba: I am trying to find out which part to share to get an answer. The code is huge! –  Feb 05 '20 at 13:51
  • @AlirezaAsadi: Did you try the precompiled header fix? – Bathsheba Feb 05 '20 at 13:51
  • @all: Code has been added. –  Feb 05 '20 at 13:57
  • It keeps yelling as follows: Severity Code Description Project File Line Suppression State Error C1083 Cannot open source file: 'C:\WINDOWS\TEMP\.NETFramework,Version=v4.5.AssemblyAttributes.cpp': No such file or directory –  Feb 05 '20 at 14:08
0

You are using cli name space. Try specifying cli::array<>.

Actually, @drescherjm had touched upon this earlier. The code is using C++/CLI. Type "array" exists in cli as well as std namespaces as array and tuple respectively. To resolve the issue, specifying cli::array will explicitly use the array. More details: https://stackoverflow.com/a/23062795/2212381

VJC
  • 3
  • 4
  • 1
    Try explaining the solution you provided. It always helps the user understand the problem better –  Apr 14 '21 at 20:38