COMS W4995 C++ for C Programmers

Index of 2025-1/code/04

Parent directory
Makefile
func1.cpp
func2.cpp
max-test.cpp
max.h

Makefile

CC  = g++
CXX = g++

CFLAGS   = -g -Wall
CXXFLAGS = -g -Wall -std=c++17

executables = max-test
objects = func1.o func2.o max-test.o

.PHONY: default
default: $(executables)

$(executables): $(objects)

$(objects): max.h

.PHONY: clean
clean:
	rm -f *~ a.out core $(objects) $(executables)

.PHONY: all
all: clean default

func1.cpp

#include "max.h"

int func1(int x, int y) {
    return Max(x, y);
}

func2.cpp

#include "max.h"

int func2(int x, int y) {
    return Max(x, y);
}

max-test.cpp

#include <string>
#include <iostream>

int Max(int x, int y) {
    return x > y ? x : y;
}

std::string Max(std::string x, std::string y) {
    return x > y ? x : y;
}

/*
#include "max.h"

const char *Max(const char *x, const char *y) {
    std::string s1(x); 
    std::string s2(y); 
    return s1 > s2 ? x : y;
}
*/

int main() {
    using namespace std;

    // (1) A function template defines a family of functions.

    cout << Max(3, 4) << ";" << Max( string{"abc"}, string{"xyz"} ) << endl;

    /*
    // (2) We can provide a function template specialization if
    //     the function template does not work for a particular type.

    cout << Max("AAA", "BBB") << endl;

    // (3) The compiler must see a template's whole definition in order to
    //     instantiate it with concrete types. Duplicate template instances
    //     in multiple object files will be resolved by the linker.

    int func1(int, int); // defined in func1.cpp; will instantiate Max(int,int)
    int func2(int, int); // defined in func2.cpp; will instantiate Max(int,int)

    cout << func1(5, 6) << ";" << func2(7, 8) << endl;
    */
}

max.h

#ifndef __MAX_H__
#define __MAX_H__

template <typename T>
const T& Max(const T& x, const T& y) {
    return x > y ? x : y;
}

#endif