#include <iostream>
#include <type_traits>

template < typename T >
void foo( const T& arg ) {

    using namespace std;

    static_assert( is_same<int,T>::value | 
                   is_same<long,T>::value |
                   is_same<std::string,T>::value , "only accept int, long and std::string as argument types" );

    cout << "foo: ";
    if( is_same<int,T>::value ) {
        cout << "<int> " << arg << endl;
    } else if( is_same<long,T>::value ) {
        cout << "<long> " << arg << endl;
    } else if( is_same<std::string,T>::value ) {
        cout << "<string> " << arg << endl;
    }
}

int main() {

    foo( 3u );
}