c++c++98

Typename and Struct definition in C++98


There is a problem with usage of typenames with struct in the old C++ standard. I have the following error:

error: no matching function for call to

This is what I get when compiling with C++98 standard. With C++11 and newer, it works as I expect.

I defined a struct with a template and in the main() function I initialized the Pair from my templated struct with some values. Then I print the members of the struct:

#include <iostream>

template <typename T>
struct Pair
{
    T first = 0;
    T second = 0;
};

int main()
{
    Pair<int> p1 { 5, 6 };        
    std::cout << p1.first << ' ' << p1.second << '\n';

    p1 = { 2, 3 }; 
    std::cout << p1.first << ' ' << p1.second << '\n';


    return 0;
}

GDB Compiler tells me: main.cpp: In function ‘int main()’: main.cpp:12:25: error: no matching function for call to ‘Pair::Pair()’ 12 | Pair<int> p1 { 5, 6 };

But if we change declaration of members in the struct to this:

struct Pair
{
    T first;
    T second;
};

It works correctly.

Can somebody explain why it works like this?


Solution

  • Default member initializers were a feature added to the language in C++11. That means that the = 0 part of your Pair member declarations is ill-formed before C++11.

    Uniform initialization syntax was also added in C++11, which means that Pair<int> p1 { 5, 6 } and p1 = { 2, 3 } are also ill-formed prior to C++11.

    Changing the definition of Pair as you did fixes the first issue, but not the second. To get the same functionality with C++98 you will need to add user-defined constructors to Pair:

    template <typename T>
    struct Pair
    {
        T first;
        T second;
    
        Pair() : first(), second() {}
        Pair(T f, T s) : first(f), second(s) {}
    };
    
    int main()
    {
        Pair<int> p1(5, 6);
        std::cout << p1.first << ' ' << p1.second << '\n';
    
        p1 = Pair<int>(2, 3);
        std::cout << p1.first << ' ' << p1.second << '\n';
    
    
        return 0;
    }