I found [a question somewhat interesting](https://stackoverflow.com/q/29358105/3258851), and went on an attempt to answer it. The author wants to compile -one- source file (which relies on template libraries) with AVX optimizations, and the rest of the project without those.

So, to see what would happen, I've created a test project like this:

*main.cpp*

```
#include <iostream>
#include <string>
#include "fn_normal.h"
#include "fn_avx.h"

int main(int argc, char* argv[])
{   
    int number = 10; // this will come from input, but let's keep it simple for now
    int result;

    if (std::string(argv[argc - 1]) == "--noavx")
        result = FnNormal(number);
    else
    {
        std::cout << "AVX selected\n";
        result = FnAVX(number);
    }

    std::cout << "Double of " << number << " is " << result << std::endl;

    return 0;
}

```

Files *fn\_normal.h* and *fn\_avx.h* contains declarations for functions `FnNormal()` and `FnAVX()` respectively, which are defined as follows:

*fn\_normal.cpp*

```
#include "fn_normal.h"
#include "double.h"

int FnNormal(int num)
{
    return RtDouble(num);
}

```

*fn\_avx.cpp*

```
#include "fn_avx.h"
#include "double.h"

int FnAVX(int num)
{
    return RtDouble(num);
}

```

And here's the template function definition:

*double.h*

```
template<typename T>
int RtDouble(T number)
{
    // Side effect: generates avx instructions
    const int N = 1000;
    float a[N], b[N];
    for (int n = 0; n < N; ++n)
    {
        a[n] = b[n] * b[n] * b[n];
    }    
    return number * 2;
}

```

Ultimately, I set `Enhanced Instruction Set` to `AVX` for the file *fn\_avx.cpp* under "Properties-> C/C++ -> Code Generation", leaving it to `Not Set` for the other sources, thus it should default to SSE2.

I thought that by doing so, the compiler would instantiate the template once for each source that includes it (and avoid violating the One-Definition Rule by mangling the template function name or some other way), and thus calling the program with the `--noavx` parameter would make it run fine in cpus without avx support.  

But the resulting program will actualy have only one machine-code version of the function, with avx instructions, and will fail on older cpus.

Disabling all other optimizations doesn't solve this issue. Also tried `No Enhanced Instructions - /arch:IA32` instead of `Not Set` as well. 

As I'm just now beginning to understand templates and such, could someone point to me **the exact details for this behavior** and what I could actually do to achieve my goal?

My compiler is MSVC 2013.