I managed to specialize the operator<< for Vector2<> and Color on MSVC 2012, but my code doesn't work on xcode 5.
namespace sf {
ostream & operator<< (ostream & os, const sf::Color &right)
{
os << right.r << " " << right.g << " " << right.b; return os;
}
template<typename Type>
inline ostream& operator<<(ostream& os,const sf::Vector2<Type>& rhs)
{
os.precision(2);
return os<<'['<<rhs.x<<", "<<rhs.y<<']';
}
}
My code is inside a header and inside include guards. I tried with and without inline, with and without namespace sf{}.
I'm getting duplicate symbol error for each .o file that I'm linking.
I'm guessing I'm not the only one specializing this operator. clang and MSVC sure seem to not compile templates the same way. What is working for you ?
I created an XCode project using SFML template project. This works, but not on my project. Precompiled headers might interfere, but I don't think so. On my project, even using specialized operator for each vector2f, vector2u and vector2i doesn't compile.
ttsty.h
#ifndef __testapp__ttsty__
#define __testapp__ttsty__
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;
using namespace sf;
template<typename Type>
ostream& operator<<(ostream& os,const sf::Vector2<Type>& rhs)
//;
{
os.precision(2);
return os<<'['<<rhs.x<<", "<<rhs.y<<']';
}
#endif /* defined(__testapp__ttsty__) */
ttsty.cpp
// nothing
main.cpp
//
// Disclamer:
// ----------
//
// This code will work only if you selected window, graphics and audio.
//
// Note that the "Run Script" build phase will copy the required frameworks
// or dylibs to your application bundle so you can execute it on any OS X
// computer.
//
// Your resource files (images, sounds, fonts, ...) are also copied to your
// application bundle. To get the path to these resource, use the helper
// method resourcePath() from ResourcePath.hpp
//
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
// Here is a small helper for you ! Have a look.
#include "ResourcePath.hpp"
#include "ttsty.h"
int main(int, char const**)
{
cout << Vector2f(432,3422);
// Create the main window
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
// Set the Icon
sf::Image icon;
if (!icon.loadFromFile(resourcePath() + "icon.png")) {
return EXIT_FAILURE;
}
window.setIcon(icon.getSize().x, icon.getSize().y, icon.getPixelsPtr());
// Load a sprite to display
sf::Texture texture;
if (!texture.loadFromFile(resourcePath() + "cute_image.jpg")) {
return EXIT_FAILURE;
}
sf::Sprite sprite(texture);
// Create a graphical text to display
sf::Font font;
if (!font.loadFromFile(resourcePath() + "sansation.ttf")) {
return EXIT_FAILURE;
}
sf::Text text("Hello SFML", font, 50);
text.setColor(sf::Color::Black);
// Load a music to play
// sf::Music music;
// if (!music.openFromFile(resourcePath() + "nice_music.ogg")) {
// return EXIT_FAILURE;
// }
// Play the music
// music.play();
// Start the game loop
while (window.isOpen())
{
// Process events
sf::Event event;
while (window.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed) {
window.close();
}
// Escape pressed : exit
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
window.close();
}
}
// Clear screen
window.clear();
// Draw the sprite
window.draw(sprite);
// Draw the string
window.draw(text);
// Update the window
window.display();
}
return EXIT_SUCCESS;
}
If I put the body of the function in the header, I get this linking error:
"std::__1::basic_ostream<char, std::__1::char_traits<char> >& operator<<<float>(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, sf::Vector2<float> const&)", referenced from:
In my project, if I put it in the header like it work inside my project, I get those linking errors:
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/quadtree.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/main.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/pathfinding.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/ptdistr.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/bars.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/game.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/sandbox.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/misc.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/spacepart.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6b2Vec2 in:
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/perlin.o
/Users/eio/Library/Developer/Xcode/DerivedData/oikoneme-fitkqpenpxxapogrbeidhlriixyt/Build/Intermediates/oikoneme.build/Debug/oikoneme.build/Objects-normal/x86_64/pathfinding2.o
ld: 10 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)