1

I am programming a template matrix with multi-threading. I need my matrix to be able to work with this code line (which i cannot change, it's a demand from my program):

Matrix<Complex>::setParallel(false);

so for this parallel (which is a bool decides if to use multi-threading or not) must be static.

So at start i defined it like that:

template<class T>
class Matrix
{
private:
...
public:
static bool parallel;
...
};

but then i got this error:

... undefined reference to 'Matrix<int>::parallel'

after a quick search i got to this question in stack overflow: Undefined reference to a static member

so i go ahead and to what the answers said. so i changed my code to:

   template<class T>
    class Matrix
    {
    private:
    ...
    public:
    static bool Matrix::paraller;
    ...
    };

and now i get this error:

extra qualification 'Matrix<T>::' on member 'paraller' [-fpermissive]

(note: i also tried static "bool Matrix::paraller;" instead, didn't help.

now i don't know how to get rid of the extra qualification error without getting back the undefined reference again.

if that matters, the whole code is in a file named: "Matrix.hpp", which i cannot change (another demand from my project).

what should i do?

Community
  • 1
  • 1
  • See http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix – juanchopanza Nov 16 '15 at 10:06
  • See [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) please. – πάντα ῥεῖ Nov 16 '15 at 10:11
  • @juanchopanza I don't see anywhere in that thread where it covers the case of static variable in a class template (which is not obvious how to handle) – M.M Nov 16 '15 at 10:12
  • and how to i provide an out-of-line definition? – One_Curious_User Nov 16 '15 at 10:15
  • By looking up "template static member definition" on Google. – Lightness Races in Orbit Nov 16 '15 at 10:16
  • @LightnessRacesinOrbit a few pages suggest `template bool Matrix::parallel;` in the header, but none of the answers explain why it's not an ODR violation to then instantiate that in two different units. (There seems to be an explicit provision in [basic.def.odr]/6 that "static data member of a class template" may be instantiated in multiple units so long as the initializer (if any) follows the rules in that clause, but it took me a while to find that) – M.M Nov 16 '15 at 10:32
  • @M.M: I don't think the average Joe really cares about _why_ it's valid, as long as it is. Of course, you and I are not those people. :) – Lightness Races in Orbit Nov 16 '15 at 10:34
  • @M.M: please feel encouraged to formulate an encyclopedic answer yourself. – decltype_auto Nov 16 '15 at 10:44
  • @decltype_auto i'm not completely sure what the answer is, otherwise I already would have :) – M.M Nov 16 '15 at 10:49
  • 1
    [This thread](http://stackoverflow.com/questions/1553854/template-static-variable) has some useful info – M.M Nov 16 '15 at 10:51
  • @M.M But then it would be an idea to ask a question yourself, wouldn't it? – decltype_auto Nov 16 '15 at 10:52
  • @decltype_auto the same question has been asked a few times already, but nobody's given a clear answer with standard references – M.M Nov 16 '15 at 10:56
  • @M.M: Well - judging by your ingenuities, "clear" appears to relative. Whether sth is an answer to the question "what should [the questioner] do?" is not. – decltype_auto Nov 16 '15 at 11:11
  • @decltype_auto i'm not sure what point you're trying to make, sorry – M.M Nov 16 '15 at 11:16
  • @M.M Try harder to get it. – decltype_auto Nov 16 '15 at 11:19

1 Answers1

1

Proper static class members usage is best described in this code snippet

struct A
{
   static bool concurrent;
};

A::concurrent = false;

or, if the member is const

struct B
{
   static const bool concurrent = false;
};

Specifying the template static class member is exactly the same. And one thing come out: static member initialization must be available at the scope of declaration. This means, you can't decouple declaration out of implementation - they must be exactly in the same program unit. Nevertheless, this is the common requirement for every template unit, whether it is an object, a function, etc.

Thus, creating a non-const template static class member is performed this way

template <typename T, typename U, typename... Rest>
struct TemplateStruct
{
   static U variable;
}

template <typename T, typename U, typename... Rest>
TemplateStruct<T, U, Rest...>::variable = U();

Where U may be any type you want, while it has a default constructor.