IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Duplicate symbol error


Sujet :

C++

  1. #1
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut Duplicate symbol error
    Bonjour,

    j'ai le petit morceau de programme suivant, dans lequel j'appelle différentes fonctions, en fonction du type à traiter. J'appelle une des fonctions SegmentInterX ou SegmentX (en fonction de mon problème), qui doit s'occuper de dispatcher le traitement à la bonne fonction (HistX, InterHistX, AvX ou FmX).
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #ifndef DILATE_H
    #define DILATE_H
     
    namespace mylib
    {
    namespace Dilate
    {
     
    void HistX(const UINT8 *src, const int sewidth, UINT8 *res) {...}
     
    void InterHistX(const UINT8 *src, const int sewidth, UINT8 *res) {...}
     
    template<typename T> void FmX(const T *src, const int sewidth, T *res) {...}
     
    template<typename T> void AvX(const T *src, const int sewidth, T *res) {...}
     
     
     
    template<typename T> void SegmentX(const T *src, const int sewidth, T *res)
    	{
    	if ( sewidth <= 13 ) AvX(src, sewidth, res) ;
    	else 
    		if ( std::is_same<T, UINT8>::value ) HistX(src, sewidth, res) ;
    		else FmX(src, sewidth, res) ;
    	}
     
    template<typename T> void SegmentInterX(const T *src, const int sewidth, T *res)
    	{
    	if ( std::is_same<T, UINT8>::value )
    		if ( sewidth <= 13 ) AvX(src, sewidth, res) ;
    		else InterHistX(src, sewidth, res) ;
    	else
    		if ( sewidth <= 13 || channel != 1 ) AvX(src, sewidth, res) ;
    		else FmX(src, sewidth, res) ;
    	}
     
    } // namespace Dilate
    } // namespace mylib
    #endif	/* DILATE_H */

    Mais lorsque je compile, j'ai une "Duplicate symbols error" pour les deux fonctions InterHistX et HistX.
    1. Pourquoi ?
    2. Pourquoi sur ces fonctions en particulier et pas sur les deux autres ?
    3. Pourquoi si je transforme ces fonctions en template (ce qui est inutile car elles ne peuvent traiter que des UINT8) ET que je fais un cast (UINT8*) lors de l'appel dans les fonctions SegmentInterX et SegmentX, alors tout fonctionne correctement ? (mais je trouve ça môche !!!)


    Merci par avance !!!

  2. #2
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Tes deux fonctions incriminées ne sont ni inline, ni template (donc inlinées), ni statiques (portée locale au fichier), donc pour deux fichiers .cpp incluant ton header, le compilateur va générer deux fois le code nécessaire à la fonction HistX et pareil pour la fonction InterHistX.
    Au moment du link il se trouve donc avec ces 2 fonctions dupliquées, et il te le dit donc.

    Plusieurs solutions: inliner tes fonctions, les rendre statiques, ou les déclarer dqns ton header et les implémenter dans un seul cpp. (je te conseille la dernière solution)

  3. #3
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Merci pour ta réponse !

    Citation Envoyé par dragonjoker59 Voir le message
    les déclarer dans ton header et les implémenter dans un seul cpp. (je te conseille la dernière solution)
    J'avais essayé... mais j'ai dû faire une bêtise. Je vais retester.
    J'ai pour l'instant utilisé une autre solution : déclarer les fonctions template, utiliser un static_assert à l'intérieur de la fonction et un cast dans la fonction qui appelle. C'est un peu moche, mais c'est la seule chose qui compilait correctement.

  4. #4
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    Merci pour ta réponse !


    J'avais essayé... mais j'ai dû faire une bêtise. Je vais retester.
    J'ai pour l'instant utiliser une autre solution : déclarer les fonctions template, utiliser un static_assert à l'intérieur de la fonction et un cast dans la fonction qui appelle. C'est un peu moche, mais c'est la seule chose qui compilait correctement.
    J'aimerais bien voir ça... Ca sent l'horreur...

  5. #5
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #ifndef DILATE_H
    #define DILATE_H
     
    namespace mylib
    {
    namespace Dilate
    {
     
    template<typename T> void HistX(const T *src, const int sewidth, T *res)
    	{
    	static_assert(std::is_same<T, UINT8>::value, "") ;
    	...
    	}
     
    template<typename T> void InterHistX(const UINTT8 *src, const int sewidth, T *res)
    	{
    	static_assert(std::is_same<T, UINT8>::value, "") ;
    	...
    	}
     
    template<typename T> void FmX(const T *src, const int sewidth, T *res) {...}
     
    template<typename T> void AvX(const T *src, const int sewidth, T *res) {...}
     
     
     
    template<typename T> void SegmentX(const T *src, const int sewidth, T *res)
    	{
    	if ( sewidth <= 13 ) AvX(src, sewidth, res) ;
    	else 
    		if ( std::is_same<T, UINT8>::value ) HistX((UINT8*)src, sewidth, (UINT8*)res) ;
    		else FmX(src, sewidth, res) ;
    	}
     
    template<typename T> void SegmentInterX(const T *src, const int sewidth, T *res)
    	{
    	if ( std::is_same<T, UINT8>::value )
    		if ( sewidth <= 13 ) AvX(src, sewidth, res) ;
    		else InterHistX((UINT8*)src, sewidth, (UINT8*)res) ;
    	else
    		if ( sewidth <= 13 || channel != 1 ) AvX(src, sewidth, res) ;
    		else FmX(src, sewidth, res) ;
    	}
     
    } // namespace Dilate
    } // namespace mylib
    #endif	/* DILATE_H */

    Du bidouillage sans aucun doute, mais ça compile. Je vais retenter en ne faisant que les déclarations dans le header.

  6. #6
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Je ne peux que te conseiller vivement d'enlever ces templates inutiles, et de faire beaucoup plus simple :

    Dilate.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #ifndef DILATE_H
    #define DILATE_H
     
    namespace mylib
    {
    namespace Dilate
    {
     
    	void HistX(const UINT8 *src, const int sewidth, UINT8 *res);
     
    	void InterHistX(const UINT8 *src, const int sewidth, UINT8 *res);
     
    	...
    	...
    	...
     
    } // namespace Dilate
    } // namespace mylib
    #endif	/* DILATE_H */
    Dilate.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include "Dilate.h"
     
    namespace mylib
    {
    namespace Dilate
    {
     
    	void HistX(const UINT8 *src, const int sewidth, UINT8 *res)
    	{
    	...
    	}
     
    	void InterHistX(const UINT8 *src, const int sewidth, UINT8 *res)
    	{
    	...
    	}
     
    } // namespace Dilate
    } // namespace mylib

  7. #7
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    C'est bien mon intention (je teste dès que j'ai un moment).
    J'avais essayé cette solution, mais j'avais dû faire une erreur car ça ne compilait pas :-(

  8. #8
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Effectivement, il semblerait qu'il y ait maintenant un autre problème :
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentInterX(const T*, int, int, int, int, int, T*, int) [with T = short unsigned int]':
    morphee_fastMorphee_DilateSegmentX.cpp:53:108: required from here
    Dilate.h:324:25: error: cannot convert 'const short unsigned int*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentInterHistX(const UINT8*, int, int, int, int, int, UINT8*, int)'
    else SegmentInterHistX(src, sizex, sizey, sizez, channel, sewidth, res, nbCPU) ;
    ^
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentInterX(const T*, int, int, int, int, int, T*, int) [with T = int]':
    morphee_fastMorphee_DilateSegmentX.cpp:71:108: required from here
    Dilate.h:324:25: error: cannot convert 'const int*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentInterHistX(const UINT8*, int, int, int, int, int, UINT8*, int)'
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentInterX(const T*, int, int, int, int, int, T*, int) [with T = float]':
    morphee_fastMorphee_DilateSegmentX.cpp:89:108: required from here
    Dilate.h:324:25: error: cannot convert 'const float*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentInterHistX(const UINT8*, int, int, int, int, int, UINT8*, int)'
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentInterX(const T*, int, int, int, int, int, T*, int) [with T = double]':
    morphee_fastMorphee_DilateSegmentX.cpp:107:108: required from here
    Dilate.h:324:25: error: cannot convert 'const double*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentInterHistX(const UINT8*, int, int, int, int, int, UINT8*, int)'
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentX(const T*, int, int, int, int, T*, int) [with T = short unsigned int]':
    morphee_fastMorphee_DilateSegmentX.cpp:155:84: required from here
    Dilate.h:315:52: error: cannot convert 'const short unsigned int*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentHistX(const UINT8*, int, int, int, int, UINT8*, int)'
    if ( std::is_same<T, UINT8>::value ) SegmentHistX(src, sizex, sizey, sizez, sewidth, res, nbCPU) ;
    ^
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentX(const T*, int, int, int, int, T*, int) [with T = int]':
    morphee_fastMorphee_DilateSegmentX.cpp:172:89: required from here
    Dilate.h:315:52: error: cannot convert 'const int*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentHistX(const UINT8*, int, int, int, int, UINT8*, int)'
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentX(const T*, int, int, int, int, T*, int) [with T = float]':
    morphee_fastMorphee_DilateSegmentX.cpp:189:89: required from here
    Dilate.h:315:52: error: cannot convert 'const float*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentHistX(const UINT8*, int, int, int, int, UINT8*, int)'
    Dilate.h: In instantiation of 'void FiReTiTiLiB::Dilate::SegmentX(const T*, int, int, int, int, T*, int) [with T = double]':
    morphee_fastMorphee_DilateSegmentX.cpp:206:89: required from here
    Dilate.h:315:52: error: cannot convert 'const double*' to 'const UINT8* {aka const unsigned char*}' for argument '1' to 'void FiReTiTiLiB::Dilate::SegmentHistX(const UINT8*, int, int, int, int, UINT8*, int)'
    Il semblerait que le test std::is_same<T, UINT8>::value ne fonctionne pas correctement et donc que le dispatch est erroné :-(

    [EDIT] Bien évidemment tout compile si je rajout un cast UINT8 dans les deux méthodes qui font les dispatch. Pourquoi est ce que ça ne compile pas sans les cast ?

  9. #9
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Mais tu donnes un int* là où un unsigned char* (a/k/a UINT8*) est attendu ! Comment veux-tu que le compilateur sache quoi faire ?
    Tu peux soit modifier l'appel, soit faire en sorte que tes fonctions puissent prendre des int*, par polymorphisme ou par template.

  10. #10
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par prgasp77 Voir le message
    Mais tu donnes un int* là où un unsigned char* (a/k/a UINT8) est attendu ! Comment veux-tu que le compilateur sache quoi faire ?
    Comme je faisais le test avant, j'espérais qu'il soit capable de faire la différence.

    Citation Envoyé par prgasp77 Voir le message
    Tu peux sois modifier l'appel
    Comment ?
    En faisant un simple cast comme j'ai fait, ou alors y a t-il mieux ?


    Citation Envoyé par prgasp77 Voir le message
    par polymorphisme ou par template.
    Ces fonctions ne peuvent traiter QUE des UINT8.

  11. #11
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    En faisant un simple cast comme j'ai fait, ou alors y a t-il mieux ?
    Un reinterpret_cast serait une très mauvaise idée, si tu veux modifier l'appel, et puisque tu passes par des pointeurs, tu dois déclarer une variable de type UINT8, lui assigner la valeur souhaitée depuis l'int, et appeler la fonction incriminée avec l'adresse de l'UINT8.

    Citation Envoyé par ToTo13 Voir le message
    Ces fonctions ne peuvent traiter QUE des UINT8.
    Tu peux les encapsuler.

  12. #12
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Désolé, je suis débutant en C++ et là j'avoue que j'ai du mal à comprendre ce que serait la solutions optimale à ce problème...

  13. #13
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Voici une idée d'encapsulation. A adapter aux besoins. Penser à nommer correctement les variable en fonction de leur utilité.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void HistX(const UINT8 *src, const int sewidth, UINT8 *res);
     
    template<class IntegerSource, class IntegerRes>
    void HistX_(IntegerSource const& src, const int sewidth, IntegerRes& res)
    { 
        UINT8 u8src(src);
        UINT8 u8res(res);
        HistX(&u8src, sewidth, &u8res);
        // res = output?
        res = u8res;
    }

  14. #14
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename T> void SegmentX(const T *src, const int sewidth, T *res)
    {
    	if ( sewidth <= 13 ) AvX(src, sewidth, res) ;
    	else 
    		if ( std::is_same<T, UINT8>::value ) HistX((UINT8*)src, sewidth, (UINT8*)res) ;
    		else FmX(src, sewidth, res) ;
    }
    Il te suffit de spécialiser cette fonction, en fonction de T :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    template<typename T> void SegmentX(const T *src, const int sewidth, T *res)
    {
    	if ( sewidth <= 13 )
    		AvX(src, sewidth, res) ;
    	else 
    		FmX(src, sewidth, res) ;
    }
     
    template<> void SegmentX< UINT8 >( const UINT8 *src, const int sewidth, UINT8 *res)
    {
    	if ( sewidth <= 13 )
    		AvX(src, sewidth, res) ;
    	else 
    		HistX(src, sewidth, res);
    }

  15. #15
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Il te suffit de spécialiser cette fonction, en fonction de T :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    template<typename T> void SegmentX(const T *src, const int sewidth, T *res)
    {
    	if ( sewidth <= 13 )
    		AvX(src, sewidth, res) ;
    	else 
    		FmX(src, sewidth, res) ;
    }
     
    template<> void SegmentX< UINT8 >( const UINT8 *src, const int sewidth, UINT8 *res)
    {
    	if ( sewidth <= 13 )
    		AvX(src, sewidth, res) ;
    	else 
    		HistX(src, sewidth, res);
    }
    Si je fais ça, j'ai à nouveau une "duplicate symbol error".

  16. #16
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 196
    Points : 17 165
    Points
    17 165
    Par défaut
    Alors, rajoute un inline (pour les spécialisations completes, je crois que c'est requis)

  17. #17
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Merci à tous, ça fonctionne !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Objective-C] duplicate symbol sur code C ( Minizip )
    Par pixman dans le forum Objective-C
    Réponses: 0
    Dernier message: 22/02/2012, 15h06
  2. duplicate resource error
    Par TommyBara dans le forum VC++ .NET
    Réponses: 1
    Dernier message: 26/08/2011, 11h54
  3. Duplicates Items error
    Par kiwi645 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 04/12/2007, 15h51
  4. Edition de lien : duplicate symbol found
    Par BainE dans le forum C
    Réponses: 4
    Dernier message: 08/02/2007, 16h53
  5. ACCESS 97 - Problème de duplication- Runtime error 3022)
    Par mohammedali07 dans le forum Runtime
    Réponses: 11
    Dernier message: 17/01/2006, 14h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo